Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net...
authorDavid S. Miller <davem@davemloft.net>
Fri, 6 Dec 2013 19:48:48 +0000 (14:48 -0500)
committerDavid S. Miller <davem@davemloft.net>
Fri, 6 Dec 2013 19:48:48 +0000 (14:48 -0500)
Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates

This series contains updates to i40e only.

Christopher Pau provides a patch to set pf_id based on device and
function numbers since NICs with ARI enabled can have function
numbers larger than 8.

Anjali provides 3 i40e patches to update hardware defines to keep
in sync with hardware updates.

Shannon provides the majority of i40e patches, with 7.  First patch
clears the admin queue head and tail registers during admin queue
shutdown. Then simplifies the admin queue head-tail-len setups to
use more virtual registers.  Provides several patches to cleanup
and fix driver load and reset procedures to make more robust.  Lastly,
provides an ethtool test for interrupts using the software interrupt.

Mitch provides some i40e patches which fixes up VF code in the PF
driver, specifically the number of vectors per VF are reported by the
hardware does not include vector 0, so we need to account for this
when checking.  In addition, cleans up debugging messages.

Kamil provides an i40e patch to fix the diagnostics test by restricting
the diagnostic test length.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
393 files changed:
Documentation/networking/ip-sysctl.txt
Documentation/networking/regulatory.txt
MAINTAINERS
drivers/bcma/host_pci.c
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_alb.h
drivers/net/bonding/bond_sysfs.c
drivers/net/ethernet/3com/3c59x.c
drivers/net/ethernet/amd/amd8111e.c
drivers/net/ethernet/amd/amd8111e.h
drivers/net/ethernet/amd/au1000_eth.c
drivers/net/ethernet/amd/au1000_eth.h
drivers/net/ethernet/broadcom/sb1250-mac.c
drivers/net/ethernet/chelsio/cxgb/common.h
drivers/net/ethernet/chelsio/cxgb/cphy.h
drivers/net/ethernet/chelsio/cxgb/cpl5_cmd.h
drivers/net/ethernet/chelsio/cxgb/cxgb2.c
drivers/net/ethernet/chelsio/cxgb/elmer0.h
drivers/net/ethernet/chelsio/cxgb/espi.c
drivers/net/ethernet/chelsio/cxgb/espi.h
drivers/net/ethernet/chelsio/cxgb/gmac.h
drivers/net/ethernet/chelsio/cxgb/mv88x201x.c
drivers/net/ethernet/chelsio/cxgb/pm3393.c
drivers/net/ethernet/chelsio/cxgb/regs.h
drivers/net/ethernet/chelsio/cxgb/sge.c
drivers/net/ethernet/chelsio/cxgb/sge.h
drivers/net/ethernet/chelsio/cxgb/subr.c
drivers/net/ethernet/chelsio/cxgb/suni1x10gexp_regs.h
drivers/net/ethernet/ibm/ibmveth.c
drivers/net/ethernet/ibm/ibmveth.h
drivers/net/ethernet/lantiq_etop.c
drivers/net/ethernet/marvell/mv643xx_eth.c
drivers/net/ethernet/marvell/pxa168_eth.c
drivers/net/ethernet/natsemi/ns83820.c
drivers/net/ethernet/netx-eth.c
drivers/net/ethernet/nvidia/forcedeth.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.h
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.h
drivers/net/ethernet/pasemi/pasemi_mac.c
drivers/net/ethernet/pasemi/pasemi_mac.h
drivers/net/ethernet/pasemi/pasemi_mac_ethtool.c
drivers/net/ethernet/qlogic/netxen/Makefile
drivers/net/ethernet/qlogic/netxen/netxen_nic.h
drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.h
drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
drivers/net/ethernet/smsc/smc911x.c
drivers/net/ethernet/smsc/smc911x.h
drivers/net/ethernet/smsc/smc91x.c
drivers/net/ethernet/smsc/smc91x.h
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/smsc/smsc911x.h
drivers/net/ethernet/smsc/smsc9420.c
drivers/net/ethernet/smsc/smsc9420.h
drivers/net/ethernet/sun/cassini.c
drivers/net/ethernet/sun/cassini.h
drivers/net/ethernet/tundra/tsi108_eth.h
drivers/net/ethernet/xircom/xirc2ps_cs.c
drivers/net/fddi/defxx.c
drivers/net/hamradio/mkiss.c
drivers/net/hyperv/hyperv_net.h
drivers/net/hyperv/netvsc.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/hyperv/rndis_filter.c
drivers/net/irda/au1k_ir.c
drivers/net/irda/esi-sir.c
drivers/net/irda/litelink-sir.c
drivers/net/irda/ma600-sir.c
drivers/net/irda/old_belkin-sir.c
drivers/net/irda/smsc-ircc2.c
drivers/net/irda/smsc-ircc2.h
drivers/net/irda/via-ircc.c
drivers/net/irda/via-ircc.h
drivers/net/irda/vlsi_ir.c
drivers/net/irda/vlsi_ir.h
drivers/net/ppp/ppp_mppe.c
drivers/net/tun.c
drivers/net/usb/asix.h
drivers/net/usb/asix_common.c
drivers/net/usb/asix_devices.c
drivers/net/usb/ax88172a.c
drivers/net/usb/ax88179_178a.c
drivers/net/usb/catc.c
drivers/net/usb/cdc_eem.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/cdc_subset.c
drivers/net/usb/cx82310_eth.c
drivers/net/usb/gl620a.c
drivers/net/usb/int51x1.c
drivers/net/usb/kaweth.c
drivers/net/usb/lg-vl600.c
drivers/net/usb/mcs7830.c
drivers/net/usb/net1080.c
drivers/net/usb/plusb.c
drivers/net/usb/rndis_host.c
drivers/net/usb/sierra_net.c
drivers/net/usb/smsc75xx.c
drivers/net/usb/smsc75xx.h
drivers/net/usb/smsc95xx.c
drivers/net/usb/smsc95xx.h
drivers/net/usb/usbnet.c
drivers/net/usb/zaurus.c
drivers/net/virtio_net.c
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath9k/Kconfig
drivers/net/wireless/ath/ath9k/Makefile
drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
drivers/net/wireless/ath/ath9k/ar9003_calib.c
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ar9003_wow.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9340_initvals.h
drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/debug.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/main.c
drivers/net/wireless/ath/ath9k/pci.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/tx99.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/wow.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/regd.c
drivers/net/wireless/ath/wcn36xx/hal.h
drivers/net/wireless/ath/wcn36xx/main.c
drivers/net/wireless/ath/wcn36xx/smd.c
drivers/net/wireless/ath/wcn36xx/wcn36xx.h
drivers/net/wireless/brcm80211/Kconfig
drivers/net/wireless/brcm80211/brcmfmac/Makefile
drivers/net/wireless/brcm80211/brcmfmac/bcdc.c [new file with mode: 0644]
drivers/net/wireless/brcm80211/brcmfmac/bcdc.h [new file with mode: 0644]
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 [deleted file]
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 [deleted file]
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
drivers/net/wireless/brcm80211/brcmfmac/fweh.h
drivers/net/wireless/brcm80211/brcmfmac/fwil.c
drivers/net/wireless/brcm80211/brcmfmac/fwil.h
drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
drivers/net/wireless/brcm80211/brcmfmac/p2p.c
drivers/net/wireless/brcm80211/brcmfmac/proto.c [new file with mode: 0644]
drivers/net/wireless/brcm80211/brcmfmac/proto.h [new file with mode: 0644]
drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
drivers/net/wireless/brcm80211/brcmfmac/usb.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmsmac/channel.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/cw1200/cw1200_sdio.c
drivers/net/wireless/cw1200/scan.c
drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/iwlegacy/3945-mac.c
drivers/net/wireless/iwlegacy/4965-mac.c
drivers/net/wireless/iwlegacy/common.c
drivers/net/wireless/iwlegacy/debug.c
drivers/net/wireless/iwlwifi/dvm/debugfs.c
drivers/net/wireless/iwlwifi/dvm/mac80211.c
drivers/net/wireless/iwlwifi/dvm/scan.c
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/scan.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwifiex/sta_cmdresp.c
drivers/net/wireless/prism54/islpci_dev.c
drivers/net/wireless/prism54/islpci_hotplug.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rtl818x/rtl8187/dev.c
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/core.c
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/regd.c
drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/net/wireless/rtlwifi/rtl8192cu/table.c
drivers/net/wireless/rtlwifi/stats.c
drivers/net/wireless/rtlwifi/usb.c
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/wireless/ti/wl1251/acx.c
drivers/net/wireless/ti/wl12xx/scan.c
drivers/net/wireless/ti/wlcore/cmd.c
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/scan.c
drivers/net/xen-netback/xenbus.c
include/linux/ieee80211.h
include/linux/sctp.h
include/net/cfg80211.h
include/net/cipso_ipv4.h
include/net/dcbevent.h
include/net/dcbnl.h
include/net/irda/discovery.h
include/net/irda/ircomm_core.h
include/net/irda/ircomm_event.h
include/net/irda/ircomm_lmp.h
include/net/irda/ircomm_param.h
include/net/irda/ircomm_ttp.h
include/net/irda/ircomm_tty.h
include/net/irda/ircomm_tty_attach.h
include/net/irda/irda_device.h
include/net/irda/irlap_event.h
include/net/irda/irlap_frame.h
include/net/irda/parameters.h
include/net/irda/qos.h
include/net/mac80211.h
include/net/mip6.h
include/net/netlabel.h
include/net/nfc/hci.h
include/net/nfc/llc.h
include/net/nfc/nci.h
include/net/nfc/nci_core.h
include/net/nfc/nfc.h
include/net/regulatory.h
include/net/sctp/auth.h
include/net/sctp/checksum.h
include/net/sctp/command.h
include/net/sctp/constants.h
include/net/sctp/sctp.h
include/net/sctp/sm.h
include/net/sctp/structs.h
include/net/sctp/tsnmap.h
include/net/sctp/ulpevent.h
include/net/sctp/ulpqueue.h
include/net/tc_act/tc_skbedit.h
include/net/tcp.h
include/uapi/linux/netfilter/xt_osf.h
include/uapi/linux/nl80211.h
include/uapi/linux/sctp.h
include/uapi/linux/snmp.h
net/bluetooth/bnep/bnep.h
net/bridge/netfilter/ebt_vlan.c
net/core/dev.c
net/dcb/dcbevent.c
net/dcb/dcbnl.c
net/dns_resolver/dns_key.c
net/dns_resolver/dns_query.c
net/dns_resolver/internal.h
net/ipv4/cipso_ipv4.c
net/ipv4/netfilter/nf_nat_snmp_basic.c
net/ipv4/proc.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_output.c
net/ipv6/ah6.c
net/ipv6/esp6.c
net/ipv6/ip6_output.c
net/ipv6/ipcomp6.c
net/ipv6/mip6.c
net/ipv6/tunnel6.c
net/ipv6/xfrm6_mode_ro.c
net/ipv6/xfrm6_tunnel.c
net/irda/af_irda.c
net/irda/discovery.c
net/irda/ircomm/ircomm_core.c
net/irda/ircomm/ircomm_event.c
net/irda/ircomm/ircomm_lmp.c
net/irda/ircomm/ircomm_param.c
net/irda/ircomm/ircomm_ttp.c
net/irda/ircomm/ircomm_tty.c
net/irda/ircomm/ircomm_tty_attach.c
net/irda/ircomm/ircomm_tty_ioctl.c
net/irda/irda_device.c
net/irda/irlap.c
net/irda/parameters.c
net/irda/qos.c
net/mac80211/cfg.c
net/mac80211/chan.c
net/mac80211/debugfs.c
net/mac80211/debugfs_sta.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_hwmp.c
net/mac80211/mesh_pathtbl.c
net/mac80211/mesh_plink.c
net/mac80211/mesh_ps.c
net/mac80211/mesh_sync.c
net/mac80211/mlme.c
net/mac80211/rate.h
net/mac80211/rc80211_minstrel.c
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rc80211_minstrel_ht_debugfs.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/status.c
net/mac80211/trace.h
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/vht.c
net/mac80211/wpa.c
net/mac80211/wpa.h
net/netfilter/ipvs/ip_vs_nfct.c
net/netfilter/xt_connmark.c
net/netfilter/xt_osf.c
net/netlabel/netlabel_addrlist.c
net/netlabel/netlabel_addrlist.h
net/netlabel/netlabel_cipso_v4.c
net/netlabel/netlabel_cipso_v4.h
net/netlabel/netlabel_domainhash.c
net/netlabel/netlabel_domainhash.h
net/netlabel/netlabel_kapi.c
net/netlabel/netlabel_mgmt.c
net/netlabel/netlabel_mgmt.h
net/netlabel/netlabel_unlabeled.c
net/netlabel/netlabel_unlabeled.h
net/netlabel/netlabel_user.c
net/netlabel/netlabel_user.h
net/packet/af_packet.c
net/sched/act_skbedit.c
net/sched/sch_multiq.c
net/sctp/associola.c
net/sctp/auth.c
net/sctp/bind_addr.c
net/sctp/chunk.c
net/sctp/command.c
net/sctp/debug.c
net/sctp/endpointola.c
net/sctp/input.c
net/sctp/inqueue.c
net/sctp/ipv6.c
net/sctp/objcnt.c
net/sctp/output.c
net/sctp/outqueue.c
net/sctp/primitive.c
net/sctp/proc.c
net/sctp/protocol.c
net/sctp/sm_make_chunk.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/sm_statetable.c
net/sctp/socket.c
net/sctp/ssnmap.c
net/sctp/sysctl.c
net/sctp/transport.c
net/sctp/tsnmap.c
net/sctp/ulpevent.c
net/sctp/ulpqueue.c
net/wireless/chan.c
net/wireless/core.c
net/wireless/core.h
net/wireless/genregdb.awk
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/reg.c
net/wireless/reg.h
net/wireless/trace.h

index 3c12d9a7ed00391d5c3f49ef80d7b1ae9abc40fe..12ba2cd9f03d9ca101ccd4d37ebbe928e5334e23 100644 (file)
@@ -156,6 +156,16 @@ tcp_app_win - INTEGER
        buffer. Value 0 is special, it means that nothing is reserved.
        Default: 31
 
+tcp_autocorking - BOOLEAN
+       Enable TCP auto corking :
+       When applications do consecutive small write()/sendmsg() system calls,
+       we try to coalesce these small writes as much as possible, to lower
+       total amount of sent packets. This is done if at least one prior
+       packet for the flow is waiting in Qdisc queues or device transmit
+       queue. Applications can still use TCP_CORK for optimal behavior
+       when they know how/when to uncork their sockets.
+       Default : 1
+
 tcp_available_congestion_control - STRING
        Shows the available congestion control choices that are registered.
        More congestion control algorithms may be available as modules,
index 9551622d0a7b845fe982076b3657ef59ef1ed6b7..356f791af5747fe4a2e1f25dea588d8b371d3d5b 100644 (file)
@@ -159,10 +159,10 @@ struct ieee80211_regdomain mydriver_jp_regdom = {
                REG_RULE(2412-20, 2484+20, 40, 6, 20, 0),
                /* IEEE 802.11a, channels 34..48 */
                REG_RULE(5170-20, 5240+20, 40, 6, 20,
-                       NL80211_RRF_PASSIVE_SCAN),
+                       NL80211_RRF_NO_IR),
                /* IEEE 802.11a, channels 52..64 */
                REG_RULE(5260-20, 5320+20, 40, 6, 20,
-                       NL80211_RRF_NO_IBSS |
+                       NL80211_RRF_NO_IR|
                        NL80211_RRF_DFS),
        }
 };
index 4afcfb4c892b76551630b3919aeed9efaedde9ed..b9ea9321adde8a58722e4b3154ee50b6395d4747 100644 (file)
@@ -1458,17 +1458,6 @@ T:       git git://github.com/kvalo/ath.git
 S:     Supported
 F:     drivers/net/wireless/ath/ath6kl/
 
-ATHEROS ATH9K WIRELESS DRIVER
-M:     "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
-M:     Jouni Malinen <jouni@qca.qualcomm.com>
-M:     Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
-M:     Senthil Balasubramanian <senthilb@qca.qualcomm.com>
-L:     linux-wireless@vger.kernel.org
-L:     ath9k-devel@lists.ath9k.org
-W:     http://wireless.kernel.org/en/users/Drivers/ath9k
-S:     Supported
-F:     drivers/net/wireless/ath/ath9k/
-
 WILOCITY WIL6210 WIRELESS DRIVER
 M:     Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
 L:     linux-wireless@vger.kernel.org
@@ -6928,6 +6917,14 @@ T:       git git://linuxtv.org/anttip/media_tree.git
 S:     Maintained
 F:     drivers/media/tuners/qt1010*
 
+QUALCOMM ATHEROS ATH9K WIRELESS DRIVER
+M:     QCA ath9k Development <ath9k-devel@qca.qualcomm.com>
+L:     linux-wireless@vger.kernel.org
+L:     ath9k-devel@lists.ath9k.org
+W:     http://wireless.kernel.org/en/users/Drivers/ath9k
+S:     Supported
+F:     drivers/net/wireless/ath/ath9k/
+
 QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
 M:     Kalle Valo <kvalo@qca.qualcomm.com>
 L:     ath10k@lists.infradead.org
index 6fb98b53533f9d708dfc2a530e1033f3f09008b9..12a4ff7513595d5b9a567d11267c625d4d9a67e0 100644 (file)
@@ -238,7 +238,6 @@ static void bcma_host_pci_remove(struct pci_dev *dev)
        pci_release_regions(dev);
        pci_disable_device(dev);
        kfree(bus);
-       pci_set_drvdata(dev, NULL);
 }
 
 #ifdef CONFIG_PM_SLEEP
index 02872405d35dc4a53d13473b31d1b517d22610d0..2250b063ab89e09006397f123ae725486f09fed5 100644 (file)
@@ -12,8 +12,7 @@
  * for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
index 4226044efd083645db9229c0f88e507eae6d410b..e09dd4bfafffcf585b8f853f7661e2e416c58602 100644 (file)
@@ -12,8 +12,7 @@
  * for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
index abf5e106edc549c053e4d3ffdecce72c4470742e..c778a26fb4da209a0d90af879137ba9a99f876aa 100644 (file)
@@ -12,8 +12,7 @@
  * for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
index ad5272b348f07debb61c540a909da8fa0e1593f1..af24c3cf821582c56cefab0b592a3e5d3392f9bd 100644 (file)
@@ -693,7 +693,7 @@ DEFINE_WINDOW_IO(16)
 DEFINE_WINDOW_IO(32)
 
 #ifdef CONFIG_PCI
-#define DEVICE_PCI(dev) (((dev)->bus == &pci_bus_type) ? to_pci_dev((dev)) : NULL)
+#define DEVICE_PCI(dev) ((dev_is_pci(dev)) ? to_pci_dev((dev)) : NULL)
 #else
 #define DEVICE_PCI(dev) NULL
 #endif
index d042511bdc1365882a3bea08626bfce6bcc714da..d6beba0bc01f475f66aa22da7733e584c99b038b 100644 (file)
@@ -24,9 +24,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
- * USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
 
 Module Name:
 
index 8baa3527ba746f289ed0aead68fd350be4bb09b0..b1fae36360d23daa1c489afe7cea325ac808b4c7 100644 (file)
@@ -13,9 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
- * USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
 
 Module Name:
 
index 427c148bb643538c1d2240036a9dd7cad1be9596..2eee5764805d71732d1af1da940f8da58202ae68 100644 (file)
@@ -27,8 +27,7 @@
  *  for more details.
  *
  *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * ########################################################################
  *
index 4b7f7ad62bb883dd08aae97187eafb25f9a432a8..ca53024f017f26ecd0b3a9c2bb0e90352bbe7c08 100644 (file)
@@ -18,8 +18,7 @@
  *  for more details.
  *
  *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * ########################################################################
  *
index c2777712da991dd72b876eac74fb991c73b12010..31a076d86709f2256c9a1ebe4ab93d0a5e7c9c41 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *
  * This driver is designed for the Broadcom SiByte SOC built-in
index 8abb46b39032df4bc13fe3ad4b0f227f9d2411e1..5dd20f7285eb754e8bb6227811019af1451e6ce0 100644 (file)
@@ -11,8 +11,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index 1f095a9fc73993432d15cb500db7bbb6b9c4695f..a4d2a4c08d3f73130c90ca06b4cff6ccd05069f9 100644 (file)
@@ -11,8 +11,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index e36d45b78cc7fc45e6e0ff4749967f33eabb151a..5249686afe713798f0e19214791e4868612e3852 100644 (file)
@@ -11,8 +11,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index 1d021059f097579b9306e458e2c8a5cd92a41948..e5987139a1aeb04ba4aef230d713813545e51a00 100644 (file)
@@ -11,8 +11,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index eef655c827d967f7dcc07f710caadb8554de577c..81526ad36339ba2bb2aea4dc7b994122510f18f0 100644 (file)
@@ -11,8 +11,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index 639ff1955739915416f9f1c40898e43c5ec9b80e..3e182eee799e64e482b1823e69b179ecef634262 100644 (file)
@@ -12,8 +12,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index 5694aad4fbc0a014c478b87cb4049a73446457c7..162de5259df929d6481d83afca3599ce0cebcf16 100644 (file)
@@ -11,8 +11,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index d42337457cf74bdc62e625a9688d1cb2728cd929..dfa77491a910d79b58c76475abf866d8a722b8d6 100644 (file)
@@ -12,8 +12,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index f7136b2fd1e5c946f8ee320a087cfbc872982039..d0cf611551a17185cef1e87b2e07b8aed955a588 100644 (file)
@@ -12,8 +12,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index eb33a31b08a01487dc17465ffbc7a4505030b9e2..ec5e05052d99ea208e8bf27ae28103cf4e73a23d 100644 (file)
@@ -12,8 +12,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index c80bf4d6d0a65e4a065d7833a10ec63a59dea536..964ce59ee16925607c3ff51f7360c4f1ea0d8d97 100644 (file)
@@ -11,8 +11,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index 8061fb0ef7edd5b8b9d5bca8d8d6a3e270c5314a..0341537cdd37f50b5824cb9df4d5b0e6f4bf9bda 100644 (file)
@@ -12,8 +12,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index b9bf16b385f7241c3cffc353e3fbc0feb798eafd..a1ba591b34312cf86e04e74ffa769486ce078024 100644 (file)
@@ -11,8 +11,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index e0a03a31e7c487489006aa57594d86cfb73e27b0..816719314cc893217693d3bc2756e4d8d5ac3013 100644 (file)
@@ -12,8 +12,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index d0f87d82566aa46cf1135d5918cfdfd37690cee6..7f79cc7ceb7522d7138be52df848262ce14870b3 100644 (file)
@@ -12,8 +12,7 @@
  * published by the Free Software Foundation.                                *
  *                                                                           *
  * You should have received a copy of the GNU General Public License along   *
- * with this program; if not, write to the Free Software Foundation, Inc.,   *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
+ * with this program; if not, see <http://www.gnu.org/licenses/>.            *
  *                                                                           *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
index 952d795230a479c79c0684ee0849a05e5e0ff631..cde0fd941f0ce6bbb8364f268a141cc1917d8e41 100644 (file)
@@ -12,8 +12,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Copyright (C) IBM Corporation, 2003, 2010
  *
index 84066bafe0576f8ac72126c43377a07bcade027b..451ba7949e152a66ee87e661e90722496792dfb8 100644 (file)
@@ -12,8 +12,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Copyright (C) IBM Corporation, 2003, 2010
  *
index 6a6c1f76d8e04406b1c6de12820a48a7d27337fd..974a007c427727d0799fc74eba161d7757b333d0 100644 (file)
@@ -9,8 +9,7 @@
  *   GNU General Public License for more details.
  *
  *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *   Copyright (C) 2011 John Crispin <blogic@openwrt.org>
  */
index 61088a6a94245144f46fa42e92fdce9eb07f1599..fa905052fbf4c220abc34505ad96058ec8ab689e 100644 (file)
@@ -33,8 +33,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index fff62460185c3ea26572a4cf7c9aa2bfe28bfb72..2ad32417a52cd5a92df5b0313a6e46d8462ac3bf 100644 (file)
@@ -19,8 +19,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/init.h>
index d3b47003a5757067f47340c60e6d2dc08d299c10..5213e73f0ea51ef146b06491fca4f8ad79d53b0e 100644 (file)
@@ -22,8 +22,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *
  * ChangeLog
index e6f0a4366f905796777aac8fd1e006b177b83bfc..31eb911e4763c691bb288912a8e48900cf986552 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/init.h>
index 2d045be4b5cf64a5921a6687b127609093df376e..ab67babbfdd1f40b487f19023f81f25398c0ab27 100644 (file)
@@ -26,8 +26,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
index 2a9003071d51a985be9b133fea76a585dabdf2d4..2a55d6d53ee61635806725d5167638b926f63363 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef _PCH_GBE_H_
index ff3ad70935a692210946557e9eb510473edb00fd..51250363566b0d3c579a76847eb65c3c2eca3dec 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "pch_gbe.h"
 #include "pch_gbe_phy.h"
index 94aaac5b057bcb0bbd9bda5bbaec8cc8db718dcc..91ce07c8306c54c34e99cc1b76f25f77feb5eb42 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #ifndef _PCH_GBE_API_H_
 #define _PCH_GBE_API_H_
index f0ceb89af93110c874eee7ec3d23cce82871d8a9..826f0ccdc23c818139d3951c953b56a3b885d6e8 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "pch_gbe.h"
 #include "pch_gbe_api.h"
index 27ffe0ebf0a686793c30f25f033895bf70ddfe51..464e91058c81157da7fa8d3c25a03b266ed0ffe6 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "pch_gbe.h"
index cf7c9b3a255b40cf6e4c949e248303994be07287..08d4be61606480d645f5e772f998b335b508ed65 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "pch_gbe.h"
index 8b7ff75fc8e0d5201c94a014c64781b632a896cc..a5cad5ea9436bae73fd8fa58f2cfb01b7c713a63 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "pch_gbe.h"
index 0cbe69206e04db47eb77956d7466937e6c357144..95ad0151ad028aca6312f3b0c65157a3f2d0ba7d 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #ifndef _PCH_GBE_PHY_H_
 #define _PCH_GBE_PHY_H_
index dbaa49e58b0cd8610c71a83c8170c7f10255453e..0734758ff5ba744fd47b917fefa61e090472d2b1 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/init.h>
index f2749d46c125f738ce38e406958015fc37246640..a5807703ab9650f176c268f828415c81a5598a5e 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef PASEMI_MAC_H
index 4825959a0efe1288712ce1080d47a45f6daf254b..25fae568261f6d2b51ea1011c4610b2019b88de7 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 
index 861a0590b1f4fd2bff47e25a0d84d9f69917c5f0..e14e60c883817c1a33b3466f1b90744d0312488b 100644 (file)
@@ -13,9 +13,7 @@
 # GNU General Public License for more details.
 #                                   
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-# MA  02111-1307, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
 # 
 # The full GNU General Public License is included in this distribution
 # in the file called "COPYING".
index 9adcdbb49476e53face68f353dd7261ffea356b3..6e426ae9469228ed55586bca15a8eef1dcb5e5c4 100644 (file)
@@ -14,9 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * The full GNU General Public License is included in this distribution
  * in the file called "COPYING".
index 1bcaf45aa8641f5302dde03a5a432dac3a71a799..6f6be57f46901a0e5eb3280c146fc6193cdc5171 100644 (file)
@@ -14,9 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * The full GNU General Public License is included in this distribution
  * in the file called "COPYING".
index 4ca2c196c98a1e79a77434e7ba56c14c2e98801c..87e073c6e291609793106bfc5646c4695b9698d2 100644 (file)
@@ -14,9 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * The full GNU General Public License is included in this distribution
  * in the file called "COPYING".
index 0c64c82b9acffdcfd58b9471f971d0eebe95a9cc..a310c2f6502a7256be2372e3c665ec8dc07f3895 100644 (file)
@@ -14,9 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * The full GNU General Public License is included in this distribution
  * in the file called "COPYING".
index 67efe754367de10d78e6bb1cbacd65caa6f1524c..b72b6bea326eaac359fe38f2ce3cc516424e7484 100644 (file)
@@ -14,9 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * The full GNU General Public License is included in this distribution
  * in the file called "COPYING".
index e2c5b6f2df0361e54a6fcb2c8f9df41098610fd4..7433c4d2160140cace3896596fc0179bcfe43f58 100644 (file)
@@ -14,9 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * The full GNU General Public License is included in this distribution
  * in the file called "COPYING".
index 7692dfd4f262db9045f285aadc194c1713fb724a..3010abb55fbdb22173930b36d896ad10934dc357 100644 (file)
@@ -14,9 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * The full GNU General Public License is included in this distribution
  * in the file called "COPYING".
index 3bec8cfebf99299ef9c3733b47033a26fe8ba7b1..70849dea32b1306400822919ca0bd547339cbd4a 100644 (file)
@@ -14,9 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * The full GNU General Public License is included in this distribution
  * in the file called "COPYING".
index 0f096a890059255170976ee78a3f169cdafb7c90..5a4278d1f7d0be1963624c48d3d8153c01555fdc 100644 (file)
@@ -17,8 +17,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Arguments:
  *      watchdog  = TX watchdog timeout
index 9965da39281b5ec720f9f2ce8851cf09a653a8b9..04b35f55df970eedc19ab57a4af88ee77d27cc61 100644 (file)
@@ -15,8 +15,7 @@
  . GNU General Public License for more details.
  .
  . You should have received a copy of the GNU General Public License
- . along with this program; if not, write to the Free Software
- . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ . along with this program; if not, see <http://www.gnu.org/licenses/>.
  .
  . Information contained in this file was obtained from the LAN9118
  . manual from SMC.  To get a copy, if you really want one, you can find
index 0c9b5d94154f8d215ddaf40d3fb252764983d73b..b84c4ddf7adddea636075ea2e12f4f51c1cfd407 100644 (file)
@@ -19,8 +19,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Arguments:
  *     io      = for the base address
index 749654b976bcf85fd07558f175274b9f01551705..47dce918eb0f49741a9dec7ae3cee68354fb7a0a 100644 (file)
@@ -18,8 +18,7 @@
  . GNU General Public License for more details.
  .
  . You should have received a copy of the GNU General Public License
- . along with this program; if not, write to the Free Software
- . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ . along with this program; if not, see <http://www.gnu.org/licenses/>.
  .
  . Information contained in this file was obtained from the LAN91C111
  . manual from SMC.  To get a copy, if you really want one, you can find
index 8564f23a679615b63df2059b9482444679193c72..6382b7c416f4a4e2e6a7769e2846f19c84565251 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ***************************************************************************
  * Rewritten, heavily based on smsc911x simple driver by SMSC.
index 9ad5e5d39a03823c4389ee5842d0ecdd0b6db5fc..23953957fed8a37e7e8daa81d6474e9d33b5413d 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ***************************************************************************/
 #ifndef __SMSC911X_H__
index f433d97aa09703eb295284f97825851f483b7807..9d6effe5f699a08a01dc64e047be64e6c898690c 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ***************************************************************************
  */
index e441402f77a2e3134d888dd7c1cb49402f27e3d7..c63c76381af66fcd70c6f3972329c8a38793c6be 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ***************************************************************************
  */
index b4d50d74ba183b29156bce538af3c5c03369d9ea..df8d383acf48ed0da087bb19d144499484ac0376 100644 (file)
@@ -14,9 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * This driver uses the sungem driver (c) David Miller
  * (davem@redhat.com) as its basis.
index b361424d5f5799209d0c21fec9acf974aed2644e..882ce168a799b158c194652a08d31249b3fa7119 100644 (file)
@@ -15,9 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * vendor id: 0x108E (Sun Microsystems, Inc.)
  * device id: 0xabba (Cassini)
index 5fee7d78dc6dd70c89de368f8e336c00e37da602..4a03c594b2b15aee763d3d8b4a8b51f60ef3a558 100644 (file)
@@ -16,9 +16,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
index bdd20b888cf647306f8fc19a78591a0241b0a2a2..7c81ffb861e8cf99d8e66490e6b3026df71879cd 100644 (file)
@@ -27,8 +27,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *
  * ALTERNATIVELY, this driver may be distributed under the terms of
index 0b40e1c46f07a15a32ab4ba17c54e610e1ccd64e..0344f71bf4a5f4a7e467875bc803453c38141fd6 100644 (file)
@@ -241,12 +241,6 @@ static char version[] =
  */
 #define NEW_SKB_SIZE (PI_RCV_DATA_K_SIZE_MAX+128)
 
-#ifdef CONFIG_PCI
-#define DFX_BUS_PCI(dev) (dev->bus == &pci_bus_type)
-#else
-#define DFX_BUS_PCI(dev) 0
-#endif
-
 #ifdef CONFIG_EISA
 #define DFX_BUS_EISA(dev) (dev->bus == &eisa_bus_type)
 #else
@@ -436,7 +430,7 @@ static void dfx_port_read_long(DFX_board_t *bp, int offset, u32 *data)
 static void dfx_get_bars(struct device *bdev,
                         resource_size_t *bar_start, resource_size_t *bar_len)
 {
-       int dfx_bus_pci = DFX_BUS_PCI(bdev);
+       int dfx_bus_pci = dev_is_pci(bdev);
        int dfx_bus_eisa = DFX_BUS_EISA(bdev);
        int dfx_bus_tc = DFX_BUS_TC(bdev);
        int dfx_use_mmio = DFX_MMIO || dfx_bus_tc;
@@ -518,7 +512,7 @@ static const struct net_device_ops dfx_netdev_ops = {
 static int dfx_register(struct device *bdev)
 {
        static int version_disp;
-       int dfx_bus_pci = DFX_BUS_PCI(bdev);
+       int dfx_bus_pci = dev_is_pci(bdev);
        int dfx_bus_tc = DFX_BUS_TC(bdev);
        int dfx_use_mmio = DFX_MMIO || dfx_bus_tc;
        const char *print_name = dev_name(bdev);
@@ -667,7 +661,7 @@ static void dfx_bus_init(struct net_device *dev)
 {
        DFX_board_t *bp = netdev_priv(dev);
        struct device *bdev = bp->bus_dev;
-       int dfx_bus_pci = DFX_BUS_PCI(bdev);
+       int dfx_bus_pci = dev_is_pci(bdev);
        int dfx_bus_eisa = DFX_BUS_EISA(bdev);
        int dfx_bus_tc = DFX_BUS_TC(bdev);
        int dfx_use_mmio = DFX_MMIO || dfx_bus_tc;
@@ -813,7 +807,7 @@ static void dfx_bus_uninit(struct net_device *dev)
 {
        DFX_board_t *bp = netdev_priv(dev);
        struct device *bdev = bp->bus_dev;
-       int dfx_bus_pci = DFX_BUS_PCI(bdev);
+       int dfx_bus_pci = dev_is_pci(bdev);
        int dfx_bus_eisa = DFX_BUS_EISA(bdev);
        u8 val;
 
@@ -967,7 +961,7 @@ static int dfx_driver_init(struct net_device *dev, const char *print_name,
 {
        DFX_board_t *bp = netdev_priv(dev);
        struct device *bdev = bp->bus_dev;
-       int dfx_bus_pci = DFX_BUS_PCI(bdev);
+       int dfx_bus_pci = dev_is_pci(bdev);
        int dfx_bus_eisa = DFX_BUS_EISA(bdev);
        int dfx_bus_tc = DFX_BUS_TC(bdev);
        int dfx_use_mmio = DFX_MMIO || dfx_bus_tc;
@@ -1877,7 +1871,7 @@ static irqreturn_t dfx_interrupt(int irq, void *dev_id)
        struct net_device *dev = dev_id;
        DFX_board_t *bp = netdev_priv(dev);
        struct device *bdev = bp->bus_dev;
-       int dfx_bus_pci = DFX_BUS_PCI(bdev);
+       int dfx_bus_pci = dev_is_pci(bdev);
        int dfx_bus_eisa = DFX_BUS_EISA(bdev);
        int dfx_bus_tc = DFX_BUS_TC(bdev);
 
@@ -3579,7 +3573,7 @@ static void dfx_unregister(struct device *bdev)
 {
        struct net_device *dev = dev_get_drvdata(bdev);
        DFX_board_t *bp = netdev_priv(dev);
-       int dfx_bus_pci = DFX_BUS_PCI(bdev);
+       int dfx_bus_pci = dev_is_pci(bdev);
        int dfx_bus_tc = DFX_BUS_TC(bdev);
        int dfx_use_mmio = DFX_MMIO || dfx_bus_tc;
        resource_size_t bar_start = 0;          /* pointer to port */
index 8e01c457015b4dc05c9fd4a85b77a0e3c0ded74b..8a6c720a4cc9a86f073cf73bfdc4157820286bfa 100644 (file)
@@ -9,8 +9,7 @@
  *  for more details.
  *
  *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl>
  * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org>
index e6fe0d80d6122fcd8dfcf7bb65fa71dac68c1e73..a26eecb1212ce735a2de234e31a12ae9a4e90b37 100644 (file)
@@ -12,8 +12,7 @@
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors:
  *   Haiyang Zhang <haiyangz@microsoft.com>
index 2b0480416b31a2586afd0467ab539e1065caeb5b..93b485b96249b32347586f6494b7e1d15ab3cc2a 100644 (file)
@@ -11,8 +11,7 @@
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors:
  *   Haiyang Zhang <haiyangz@microsoft.com>
index 524f713f60170b2d5632bbac6958ae0529a80b1c..9184c82d5c502f6743c6431fe9d61e7f80106c2a 100644 (file)
@@ -11,8 +11,7 @@
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors:
  *   Haiyang Zhang <haiyangz@microsoft.com>
index 0775f0aefd1e67715ab77750ac898660d3ca6267..1084e5de3ceb4c805d2ef9e98b90c6d68a9a9991 100644 (file)
@@ -11,8 +11,7 @@
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors:
  *   Haiyang Zhang <haiyangz@microsoft.com>
index 7a1f684edcb597b5cdd499d54517708f598a1e7a..5b7a665c6d8365fddb4148c188bd7665f094223a 100644 (file)
@@ -15,8 +15,7 @@
  *  for more details.
  *
  *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/init.h>
index a908df7c4b9dcada826e9da35e3ecfe17b0febe8..019a3e848bcb7d7db1465fd5c3129a765c8a0fe0 100644 (file)
@@ -25,9 +25,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index d6d9d2e5ad492306eb695692e8b40fe78010331d..6827777cbeea95c77ead150bccd6dc3c97a2a5d8 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index e91216452379f318d53b2c953555593d7c796eae..a9a81358477bcafc817b16497312ab29b850b760 100644 (file)
@@ -25,9 +25,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index 75714bc7103065501bc5bfc938584a06b77cebae..f237136f38278ca018f6d612bd48a28568b50104 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index 0dcdf1592f6b2ee516d2d57c34cf78a5dd425441..282120430f1271bfbfb4ea06b301d4560ef1daf0 100644 (file)
@@ -34,9 +34,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 317b7fd69bb35a6035445f44ab8e6b503a6f0004..4829fa22cb299f8286766154853d199dcb6a3b09 100644 (file)
@@ -25,9 +25,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 9abaec27f96259c5c3360d12f7ffb3dfc3699832..26cb45d597028a242632b225f0d1090ab586cd06 100644 (file)
@@ -17,8 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+this program; if not, see <http://www.gnu.org/licenses/>.
 
 F01 Oct/02/02: Modify code for V0.11(move out back to back transfer)
 F02 Oct/28/02: Add SB device ID for 3147 and 3177.
index f903a6a2dcb7d5c5969ec5f384dbb4705e916670..7ce820ecc361519243a98f2f150eb145b2715f74 100644 (file)
@@ -18,8 +18,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+this program; if not, see <http://www.gnu.org/licenses/>.
 
  * Comment:
  * jul/08/2002 : Rx buffer length should use Rx ring ptr.      
index c5bd58b4d8a82a61ad2a87a3f854f7d6b033e803..cc9b8665e73c31890a9132b5bafe476d3360c0bc 100644 (file)
@@ -15,9 +15,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index a076eb1253490ac4557feb743c78d368efa4bbe4..56399204e68cf38503d831585e7931ef9b04d3f7 100644 (file)
@@ -18,9 +18,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 9a1849a83e2ad06778a8b0fb612641ce17a8128d..911b21602ff271885c2dbfb4c5c04f69fb028e7e 100644 (file)
@@ -27,8 +27,7 @@
  *   GNU General Public License for more details.
  *
  *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *
  * Changelog:
index 782e38bfc1eeea38215492aee5aaa587cc534525..5ac2877a89c35e6de65dfb1f2cb962de9ae303a9 100644 (file)
@@ -110,7 +110,7 @@ struct tap_filter {
        unsigned char   addr[FLT_EXACT_COUNT][ETH_ALEN];
 };
 
-/* DEFAULT_MAX_NUM_RSS_QUEUES were choosed to let the rx/tx queues allocated for
+/* DEFAULT_MAX_NUM_RSS_QUEUES were chosen to let the rx/tx queues allocated for
  * the netdevice to be fit in one page. So we can make sure the success of
  * memory allocation. TODO: increase the limit. */
 #define MAX_TAP_QUEUES DEFAULT_MAX_NUM_RSS_QUEUES
@@ -119,7 +119,7 @@ struct tap_filter {
 #define TUN_FLOW_EXPIRE (3 * HZ)
 
 /* A tun_file connects an open character device to a tuntap netdevice. It
- * also contains all socket related strctures (except sock_fprog and tap_filter)
+ * also contains all socket related structures (except sock_fprog and tap_filter)
  * to serve as one transmit queue for tuntap device. The sock_fprog and
  * tap_filter were kept in tun_struct since they were used for filtering for the
  * netdevice not for a specific queue (at least I didn't see the requirement for
@@ -342,7 +342,7 @@ unlock:
 }
 
 /* We try to identify a flow through its rxhash first. The reason that
- * we do not check rxq no. is becuase some cards(e.g 82599), chooses
+ * we do not check rxq no. is because some cards(e.g 82599), chooses
  * the rxq based on the txq where the last packet of the flow comes. As
  * the userspace application move between processors, we may get a
  * different rxq no. here. If we could not get rxhash, then we would
@@ -531,7 +531,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filte
 
        err = 0;
 
-       /* Re-attach the filter to presist device */
+       /* Re-attach the filter to persist device */
        if (!skip_filter && (tun->filter_attached == true)) {
                err = sk_attach_filter(&tun->fprog, tfile->socket.sk);
                if (!err)
@@ -819,9 +819,9 @@ static void tun_poll_controller(struct net_device *dev)
         * Tun only receives frames when:
         * 1) the char device endpoint gets data from user space
         * 2) the tun socket gets a sendmsg call from user space
-        * Since both of those are syncronous operations, we are guaranteed
+        * Since both of those are synchronous operations, we are guaranteed
         * never to have pending data when we poll for it
-        * so theres nothing to do here but return.
+        * so there is nothing to do here but return.
         * We need this though so netpoll recognizes us as an interface that
         * supports polling, which enables bridge devices in virt setups to
         * still use netconsole
index bdaa12d07a127fae11a6209986d0473c32644f27..bad857aacd1a6898bf5e19d0fc8246dcd514085c 100644 (file)
@@ -16,8 +16,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef _ASIX_H
index 577c72d5f3690dd3917d05fc8dcb9f9d89c354a4..5c55f11572baa0a3e0dd3877ae886935cb8a6eb9 100644 (file)
@@ -16,8 +16,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "asix.h"
index 386a3df53678a23761308938221f4aa79b520538..9765a7d4766dcd4a717bd7cd0bea56c71953deb1 100644 (file)
@@ -16,8 +16,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "asix.h"
index 723b3879ecc2e195515037404f1bb4eae8a6f3f4..5f18fcb8dcc767494d26373aabc4d137592eb14d 100644 (file)
@@ -21,8 +21,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "asix.h"
index 8e8d0fcd4979f10c71ff1e37140313d255429847..d6f64dad05bcb707c0c26dbe2886abd73e760db1 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/module.h>
index df507e6dbb9c99d9a15f718128e008f06ba11cdb..da6b8a5dcc0debc9522758f8f6558c474d19dd4e 100644 (file)
@@ -24,8 +24,7 @@
  * GNU General Public License for more details.
  * 
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  * 
  * Should you need to contact me, the author, you can do so either by
  * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
index 08d55b6bf272bc5293a8a8d059d54d652aca27e1..57fd7170ae60849bf377211ca285c2b7df7d5be8 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/module.h>
index 2023f3ea891e6bf75f0c62d3d78213e30d1a11f4..4b1c0f3f727da0d8061782dc1cf7d0c2caeeba6f 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 // #define     DEBUG                   // error path messages, extra info
index 0d1fe89ae0bde94d813a44bc9c507fa3dac01f16..3b2593a7602b76291bf61bcaee7b72ed9041459f 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/module.h>
index 1e207f086b759416a916cb9180af1be85e8a3fce..5233e6d070ec9d1758a23aca962bed3d7a2eb459 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/module.h>
index a7e3f4e55bf3651b3874710ffcf4cfcdeb37e299..3569da1135c140f65a7b1c56430ca064594b8a5a 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 // #define     DEBUG                   // error path messages, extra info
index ace9e74ffbdd90ece5da77dab76890d46877a344..4ff70b22c6eec0e0516373b02b66c71fae158028 100644 (file)
@@ -20,8 +20,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/module.h>
index afb117c16d2d3688b62952ec2251f29c29eee06c..250fc21d97810a0cb212d0abc11d25168479a8fc 100644 (file)
@@ -25,8 +25,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software Foundation,
- *     Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ****************************************************************/
 
index 808d6506da41293ed9689ab2c064cfca7a99853d..acfcc32b323d87c1b6f4e64788802af932f74319 100644 (file)
@@ -15,8 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
index 03832d3780aa6134059dc4768bb7614d71075b82..aea68bc33583c88a32a42ee41fea24111b5e5a2a 100644 (file)
@@ -36,8 +36,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/crc32.h>
index 93e0716a118c309f90859e4ee913d2e2e32b41e0..8b2493f05a1c6415e4fd731d6fc5b1567a705262 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 // #define     DEBUG                   // error path messages, extra info
index 0fcc8e65a06800a390b2aab1ab4ff1f7486cd051..ee705b7bba08b09f71051b83b52099446406dc3c 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 // #define     DEBUG                   // error path messages, extra info
index cc49aac70224910f63fc6c5ed6b0b2fc720ff674..72aee8516ca8511c7b02d307ac51dcf2425fa3f2 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/module.h>
 #include <linux/init.h>
index a79e9d3349284ac7c8371ae495d03110f87a3d42..a251588762ec6aa4053ec8af337e714411ec877c 100644 (file)
@@ -21,8 +21,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #define DRIVER_VERSION "v.2.0"
index 66ebbacf066f6692ba21d2fa07538535827074b9..0217b282e7ecaf3fdb6cd47ad7f813fddc71a445 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *****************************************************************************/
 
index 67eba39e6ee23cb28248f0be099313c320339799..2c7ea8fd184f2ab397e42c0c79408aea9554eb45 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *****************************************************************************/
 
index 3f38ba868f6182152093e8efad0a864439c5cef0..96f5eee20fa43b84da5ac21f5752ebb65785c99b 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *****************************************************************************/
 
index f360ee372554d5b1ce40c789aac44a6d066fc730..526faa0c44e65ee76c420cd4aa104a72da213ee5 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *****************************************************************************/
 
index 8494bb53ebdc9f33abee1d8e5a27f7d0dea3cc17..56c175ebae3ca9b55a40e019e61b5a59840d35de 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
index 35c90307d473009250aa7e711d8e4949db891607..25d1e667a0616a45a0fdcaeb43be83ecb79db048 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 // #define     DEBUG                   // error path messages, extra info
index 916241d16c6764c117f80fa7109bdbff7dfdb714..5c24288814db775175ae28d8b37849ac9c0a760d 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 //#define DEBUG
 #include <linux/netdevice.h>
index 97ac8c87cba232646f5f82617ea396b8c2573870..06fe2b8fa22dd40a0817b1f38725d6106491fa34 100644 (file)
@@ -1351,12 +1351,12 @@ static int ath10k_update_channel_list(struct ath10k *ar)
                        ch->allow_vht = true;
 
                        ch->allow_ibss =
-                               !(channel->flags & IEEE80211_CHAN_NO_IBSS);
+                               !(channel->flags & IEEE80211_CHAN_NO_IR);
 
                        ch->ht40plus =
                                !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
 
-                       passive = channel->flags & IEEE80211_CHAN_PASSIVE_SCAN;
+                       passive = channel->flags & IEEE80211_CHAN_NO_IR;
                        ch->passive = passive;
 
                        ch->freq = channel->center_freq;
index 2437ad26949d1c43617204fc7c887bf196a1e2f5..fd4c89df67e1658ae404686a911fc62607cee1cd 100644 (file)
@@ -1109,7 +1109,9 @@ void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
                                (mode == WMI_11G_HT20) ?
                                        NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
 
+       mutex_lock(&vif->wdev.mtx);
        cfg80211_ch_switch_notify(vif->ndev, &chandef);
+       mutex_unlock(&vif->wdev.mtx);
 }
 
 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
@@ -3169,12 +3171,15 @@ 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,
-                         unsigned int wait, const u8 *buf, size_t len,
-                         bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+                         struct cfg80211_mgmt_tx_params *params, u64 *cookie)
 {
        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
        struct ath6kl *ar = ath6kl_priv(vif->ndev);
+       struct ieee80211_channel *chan = params->chan;
+       const u8 *buf = params->buf;
+       size_t len = params->len;
+       unsigned int wait = params->wait;
+       bool no_cck = params->no_cck;
        u32 id, freq;
        const struct ieee80211_mgmt *mgmt;
        bool more_data, queued;
index 32f139e2e897e255b4c378c33c6d99df8abd51e0..30d273c61bffb8f4e040e5f2eaddd37154f439f7 100644 (file)
@@ -86,7 +86,7 @@ config ATH9K_DFS_CERTIFIED
 
 config ATH9K_TX99
        bool "Atheros ath9k TX99 testing support"
-       depends on CFG80211_CERTIFICATION_ONUS
+       depends on ATH9K_DEBUGFS && CFG80211_CERTIFICATION_ONUS
        default n
        ---help---
          Say N. This should only be enabled on systems undergoing
@@ -104,6 +104,14 @@ config ATH9K_TX99
          be evaluated to meet the RF exposure limits set forth in the
          governmental SAR regulations.
 
+config ATH9K_WOW
+       bool "Wake on Wireless LAN support (EXPERIMENTAL)"
+       depends on ATH9K && PM
+       default n
+       ---help---
+         This option enables Wake on Wireless LAN support for certain cards.
+         Currently, AR9462 is supported.
+
 config ATH9K_LEGACY_RATE_CONTROL
        bool "Atheros ath9k rate control"
        depends on ATH9K
index 6205ef5a9321e8072c283d24e8e7814b2a8392df..337c459eda284770c61dbb654b1762aac3965e9b 100644 (file)
@@ -13,9 +13,9 @@ ath9k-$(CONFIG_ATH9K_PCI) += pci.o
 ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
 ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
 ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
-ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += \
-               dfs.o
-ath9k-$(CONFIG_PM_SLEEP) += wow.o
+ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o
+ath9k-$(CONFIG_ATH9K_TX99) += tx99.o
+ath9k-$(CONFIG_ATH9K_WOW) += wow.o
 
 obj-$(CONFIG_ATH9K) += ath9k.o
 
@@ -41,6 +41,8 @@ ath9k_hw-y:=  \
                ar9003_eeprom.o \
                ar9003_paprd.o
 
+ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o
+
 ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
                                           ar9003_mci.o
 obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
index 7546b9a7dcbfa2252bf896e70fe48ad38b3b4646..e7cdf1100f56bc1ea52273c6b756779e1a3b2ff2 100644 (file)
@@ -352,7 +352,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = {
        {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
        {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
        {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
-       {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
+       {0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982},
        {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
        {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
@@ -378,9 +378,9 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
        {0x00009814, 0x9280c00a},
        {0x00009818, 0x00000000},
        {0x0000981c, 0x00020028},
-       {0x00009834, 0x6400a290},
+       {0x00009834, 0x6400a190},
        {0x00009838, 0x0108ecff},
-       {0x0000983c, 0x0d000600},
+       {0x0000983c, 0x14000600},
        {0x00009880, 0x201fff00},
        {0x00009884, 0x00001042},
        {0x000098a4, 0x00200400},
@@ -401,7 +401,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
        {0x00009d04, 0x40206c10},
        {0x00009d08, 0x009c4060},
        {0x00009d0c, 0x9883800a},
-       {0x00009d10, 0x01834061},
+       {0x00009d10, 0x01884061},
        {0x00009d14, 0x00c0040b},
        {0x00009d18, 0x00000000},
        {0x00009e08, 0x0038230c},
@@ -459,7 +459,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
        {0x0000a3e8, 0x20202020},
        {0x0000a3ec, 0x20202020},
        {0x0000a3f0, 0x00000000},
-       {0x0000a3f4, 0x00000246},
+       {0x0000a3f4, 0x00000000},
        {0x0000a3f8, 0x0c9bd380},
        {0x0000a3fc, 0x000f0f01},
        {0x0000a400, 0x8fa91f01},
@@ -644,7 +644,7 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
        {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
        {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
        {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+       {0x0000a410, 0x000050d4, 0x000050d4, 0x000050d9, 0x000050d9},
        {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
        {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
        {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
@@ -1086,8 +1086,8 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
        {0x0000b074, 0x00000000},
        {0x0000b078, 0x00000000},
        {0x0000b07c, 0x00000000},
-       {0x0000b080, 0x2a2d2f32},
-       {0x0000b084, 0x21232328},
+       {0x0000b080, 0x23232323},
+       {0x0000b084, 0x21232323},
        {0x0000b088, 0x19191c1e},
        {0x0000b08c, 0x12141417},
        {0x0000b090, 0x07070e0e},
@@ -1385,9 +1385,9 @@ static const u32 ar9300_2p2_mac_core[][2] = {
        {0x000081f8, 0x00000000},
        {0x000081fc, 0x00000000},
        {0x00008240, 0x00100000},
-       {0x00008244, 0x0010f424},
+       {0x00008244, 0x0010f400},
        {0x00008248, 0x00000800},
-       {0x0000824c, 0x0001e848},
+       {0x0000824c, 0x0001e800},
        {0x00008250, 0x00000000},
        {0x00008254, 0x00000000},
        {0x00008258, 0x00000000},
@@ -1726,16 +1726,23 @@ static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
 
 static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = {
        /* Addr      allmodes  */
-       {0x00004040, 0x08253e5e},
+       {0x00004040, 0x0825365e},
        {0x00004040, 0x0008003b},
        {0x00004044, 0x00000000},
 };
 
 static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = {
        /* Addr      allmodes  */
-       {0x00004040, 0x08213e5e},
+       {0x00004040, 0x0821365e},
        {0x00004040, 0x0008003b},
        {0x00004044, 0x00000000},
 };
 
+static const u32 ar9300_2p2_baseband_core_txfir_coeff_japan_2484[][2] = {
+       /* Addr      allmodes  */
+       {0x0000a398, 0x00000000},
+       {0x0000a39c, 0x6f7f0301},
+       {0x0000a3a0, 0xca9228ee},
+};
+
 #endif /* INITVALS_9003_2P2_H */
index 22934d3ca54413fa9558a928fdccbc4ab108131a..aa0127265746941e473263d84e4b57d8177d0608 100644 (file)
@@ -1040,14 +1040,14 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
        }
 }
 
-static bool ar9003_hw_init_cal(struct ath_hw *ah,
-                              struct ath9k_channel *chan)
+static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah,
+                                    struct ath9k_channel *chan)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_cal_data *caldata = ah->caldata;
        bool txiqcal_done = false;
        bool is_reusable = true, status = true;
-       bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false;
+       bool run_rtt_cal = false, run_agc_cal;
        bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
        u32 rx_delay = 0;
        u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
@@ -1119,22 +1119,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
                        REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
                                    AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
                txiqcal_done = run_agc_cal = true;
-       } else if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) {
-               run_agc_cal = true;
-               sep_iq_cal = true;
        }
 
 skip_tx_iqcal:
        if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
                ar9003_mci_init_cal_req(ah, &is_reusable);
 
-       if (sep_iq_cal) {
-               txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
-               REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
-               udelay(5);
-               REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
-       }
-
        if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
                rx_delay = REG_READ(ah, AR_PHY_RX_DELAY);
                /* Disable BB_active */
@@ -1228,13 +1218,109 @@ skip_tx_iqcal:
        return true;
 }
 
+static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
+                                  struct ath9k_channel *chan)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_hw_cal_data *caldata = ah->caldata;
+       bool txiqcal_done = false;
+       bool is_reusable = true, status = true;
+       bool run_agc_cal = false, sep_iq_cal = false;
+
+       /* Use chip chainmask only for calibration */
+       ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
+
+       if (ah->enabled_cals & TX_CL_CAL) {
+               REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+               run_agc_cal = true;
+       }
+
+       if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
+               goto skip_tx_iqcal;
+
+       /* Do Tx IQ Calibration */
+       REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
+                     AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
+                     DELPT);
+
+       /*
+        * For AR9485 or later chips, TxIQ cal runs as part of
+        * AGC calibration. Specifically, AR9550 in SoC chips.
+        */
+       if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
+               txiqcal_done = true;
+               run_agc_cal = true;
+       } else {
+               sep_iq_cal = true;
+               run_agc_cal = true;
+       }
+
+       /*
+        * In the SoC family, this will run for AR9300, AR9331 and AR9340.
+        */
+       if (sep_iq_cal) {
+               txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
+               REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+               udelay(5);
+               REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+       }
+
+skip_tx_iqcal:
+       if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
+               /* Calibrate the AGC */
+               REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+                         REG_READ(ah, AR_PHY_AGC_CONTROL) |
+                         AR_PHY_AGC_CONTROL_CAL);
+
+               /* Poll for offset calibration complete */
+               status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+                                      AR_PHY_AGC_CONTROL_CAL,
+                                      0, AH_WAIT_TIMEOUT);
+       }
+
+       if (!status) {
+               ath_dbg(common, CALIBRATE,
+                       "offset calibration failed to complete in %d ms; noisy environment?\n",
+                       AH_WAIT_TIMEOUT / 1000);
+               return false;
+       }
+
+       if (txiqcal_done)
+               ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
+
+       /* Revert chainmask to runtime parameters */
+       ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+
+       /* Initialize list pointers */
+       ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+
+       INIT_CAL(&ah->iq_caldata);
+       INSERT_CAL(ah, &ah->iq_caldata);
+       ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
+
+       /* Initialize current pointer to first element in list */
+       ah->cal_list_curr = ah->cal_list;
+
+       if (ah->cal_list_curr)
+               ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
+
+       if (caldata)
+               caldata->CalValid = 0;
+
+       return true;
+}
+
 void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
 {
        struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
        struct ath_hw_ops *ops = ath9k_hw_ops(ah);
 
+       if (AR_SREV_9485(ah) || AR_SREV_9462(ah) || AR_SREV_9565(ah))
+               priv_ops->init_cal = ar9003_hw_init_cal_pcoem;
+       else
+               priv_ops->init_cal = ar9003_hw_init_cal_soc;
+
        priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
-       priv_ops->init_cal = ar9003_hw_init_cal;
        priv_ops->setup_calibration = ar9003_hw_setup_calibration;
 
        ops->calibrate = ar9003_hw_calibrate;
index 20e49095db2ae2ba0c2d7d83071aa2a14a81252d..d8c1eee8ea53014dfde6536d507ec36862b0062f 100644 (file)
@@ -26,6 +26,7 @@
 #include "ar9462_2p0_initvals.h"
 #include "ar9462_2p1_initvals.h"
 #include "ar9565_1p0_initvals.h"
+#include "ar9565_1p1_initvals.h"
 
 /* General hardware code for the AR9003 hadware family */
 
@@ -148,7 +149,9 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                                ar9340Modes_high_ob_db_tx_gain_table_1p0);
 
                INIT_INI_ARRAY(&ah->iniModesFastClock,
-                               ar9340Modes_fast_clock_1p0);
+                              ar9340Modes_fast_clock_1p0);
+               INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+                              ar9340_1p0_baseband_core_txfir_coeff_japan_2484);
 
                if (!ah->is_clk_25mhz)
                        INIT_INI_ARRAY(&ah->iniAdditional,
@@ -223,6 +226,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                               ar9462_2p1_modes_fast_clock);
                INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
                               ar9462_2p1_baseband_core_txfir_coeff_japan_2484);
+               INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                              ar9462_2p1_pciephy_clkreq_disable_L1);
+               INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+                              ar9462_2p1_pciephy_clkreq_disable_L1);
        } else if (AR_SREV_9462_20(ah)) {
 
                INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core);
@@ -247,18 +254,18 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                                ar9462_2p0_soc_postamble);
 
                INIT_INI_ARRAY(&ah->iniModesRxGain,
-                               ar9462_common_rx_gain_table_2p0);
+                               ar9462_2p0_common_rx_gain);
 
                /* Awake -> Sleep Setting */
                INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                              ar9462_pciephy_clkreq_disable_L1_2p0);
+                              ar9462_2p0_pciephy_clkreq_disable_L1);
                /* Sleep -> Awake Setting */
                INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-                              ar9462_pciephy_clkreq_disable_L1_2p0);
+                              ar9462_2p0_pciephy_clkreq_disable_L1);
 
                /* Fast clock modal settings */
                INIT_INI_ARRAY(&ah->iniModesFastClock,
-                               ar9462_modes_fast_clock_2p0);
+                               ar9462_2p0_modes_fast_clock);
 
                INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
                               ar9462_2p0_baseband_core_txfir_coeff_japan_2484);
@@ -330,7 +337,44 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                                ar9580_1p0_low_ob_db_tx_gain_table);
 
                INIT_INI_ARRAY(&ah->iniModesFastClock,
-                               ar9580_1p0_modes_fast_clock);
+                              ar9580_1p0_modes_fast_clock);
+               INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+                              ar9580_1p0_baseband_core_txfir_coeff_japan_2484);
+       } else if (AR_SREV_9565_11_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+                              ar9565_1p1_mac_core);
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+                              ar9565_1p1_mac_postamble);
+
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+                              ar9565_1p1_baseband_core);
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+                              ar9565_1p1_baseband_postamble);
+
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+                              ar9565_1p1_radio_core);
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+                              ar9565_1p1_radio_postamble);
+
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+                              ar9565_1p1_soc_preamble);
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+                              ar9565_1p1_soc_postamble);
+
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                              ar9565_1p1_Common_rx_gain_table);
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9565_1p1_Modes_lowest_ob_db_tx_gain_table);
+
+               INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                              ar9565_1p1_pciephy_clkreq_disable_L1);
+               INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+                              ar9565_1p1_pciephy_clkreq_disable_L1);
+
+               INIT_INI_ARRAY(&ah->iniModesFastClock,
+                               ar9565_1p1_modes_fast_clock);
+               INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+                              ar9565_1p1_baseband_core_txfir_coeff_japan_2484);
        } else if (AR_SREV_9565(ah)) {
                INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
                               ar9565_1p0_mac_core);
@@ -411,7 +455,9 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 
                /* Fast clock modal settings */
                INIT_INI_ARRAY(&ah->iniModesFastClock,
-                               ar9300Modes_fast_clock_2p2);
+                              ar9300Modes_fast_clock_2p2);
+               INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+                              ar9300_2p2_baseband_core_txfir_coeff_japan_2484);
        }
 }
 
@@ -440,7 +486,10 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
                        ar9462_2p1_modes_low_ob_db_tx_gain);
        else if (AR_SREV_9462_20(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9462_modes_low_ob_db_tx_gain_table_2p0);
+                       ar9462_2p0_modes_low_ob_db_tx_gain);
+       else if (AR_SREV_9565_11(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9565_1p1_modes_low_ob_db_tx_gain_table);
        else if (AR_SREV_9565(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                               ar9565_1p0_modes_low_ob_db_tx_gain_table);
@@ -474,7 +523,10 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
                        ar9462_2p1_modes_high_ob_db_tx_gain);
        else if (AR_SREV_9462_20(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9462_modes_high_ob_db_tx_gain_table_2p0);
+                       ar9462_2p0_modes_high_ob_db_tx_gain);
+       else if (AR_SREV_9565_11(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9565_1p1_modes_high_ob_db_tx_gain_table);
        else if (AR_SREV_9565(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                               ar9565_1p0_modes_high_ob_db_tx_gain_table);
@@ -500,6 +552,9 @@ static void ar9003_tx_gain_table_mode2(struct ath_hw *ah)
        else if (AR_SREV_9580(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                        ar9580_1p0_low_ob_db_tx_gain_table);
+       else if (AR_SREV_9565_11(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9565_1p1_modes_low_ob_db_tx_gain_table);
        else if (AR_SREV_9565(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                               ar9565_1p0_modes_low_ob_db_tx_gain_table);
@@ -525,6 +580,9 @@ static void ar9003_tx_gain_table_mode3(struct ath_hw *ah)
        else if (AR_SREV_9580(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                        ar9580_1p0_high_power_tx_gain_table);
+       else if (AR_SREV_9565_11(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9565_1p1_modes_high_power_tx_gain_table);
        else if (AR_SREV_9565(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                               ar9565_1p0_modes_high_power_tx_gain_table);
@@ -546,7 +604,7 @@ static void ar9003_tx_gain_table_mode4(struct ath_hw *ah)
                       ar9462_2p1_modes_mix_ob_db_tx_gain);
        else if (AR_SREV_9462_20(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
-                      ar9462_modes_mix_ob_db_tx_gain_table_2p0);
+                      ar9462_2p0_modes_mix_ob_db_tx_gain);
        else
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                        ar9300Modes_mixed_ob_db_tx_gain_table_2p2);
@@ -581,6 +639,13 @@ static void ar9003_tx_gain_table_mode6(struct ath_hw *ah)
                        ar9580_1p0_type6_tx_gain_table);
 }
 
+static void ar9003_tx_gain_table_mode7(struct ath_hw *ah)
+{
+       if (AR_SREV_9340(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9340_cus227_tx_gain_table_1p0);
+}
+
 typedef void (*ath_txgain_tab)(struct ath_hw *ah);
 
 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
@@ -593,6 +658,7 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
                ar9003_tx_gain_table_mode4,
                ar9003_tx_gain_table_mode5,
                ar9003_tx_gain_table_mode6,
+               ar9003_tx_gain_table_mode7,
        };
        int idx = ar9003_hw_get_tx_gain_idx(ah);
 
@@ -629,7 +695,10 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
                                ar9462_2p1_common_rx_gain);
        else if (AR_SREV_9462_20(ah))
                INIT_INI_ARRAY(&ah->iniModesRxGain,
-                               ar9462_common_rx_gain_table_2p0);
+                               ar9462_2p0_common_rx_gain);
+       else if (AR_SREV_9565_11(ah))
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                              ar9565_1p1_Common_rx_gain_table);
        else if (AR_SREV_9565(ah))
                INIT_INI_ARRAY(&ah->iniModesRxGain,
                               ar9565_1p0_Common_rx_gain_table);
@@ -657,7 +726,7 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
                        ar9462_2p1_common_wo_xlna_rx_gain);
        else if (AR_SREV_9462_20(ah))
                INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9462_common_wo_xlna_rx_gain_table_2p0);
+                       ar9462_2p0_common_wo_xlna_rx_gain);
        else if (AR_SREV_9550(ah)) {
                INIT_INI_ARRAY(&ah->iniModesRxGain,
                        ar955x_1p0_common_wo_xlna_rx_gain_table);
@@ -666,6 +735,9 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
        } else if (AR_SREV_9580(ah))
                INIT_INI_ARRAY(&ah->iniModesRxGain,
                        ar9580_1p0_wo_xlna_rx_gain_table);
+       else if (AR_SREV_9565_11(ah))
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                              ar9565_1p1_common_wo_xlna_rx_gain_table);
        else if (AR_SREV_9565(ah))
                INIT_INI_ARRAY(&ah->iniModesRxGain,
                               ar9565_1p0_common_wo_xlna_rx_gain_table);
@@ -687,7 +759,7 @@ static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
                               ar9462_2p1_baseband_postamble_5g_xlna);
        } else if (AR_SREV_9462_20(ah)) {
                INIT_INI_ARRAY(&ah->iniModesRxGain,
-                              ar9462_common_mixed_rx_gain_table_2p0);
+                              ar9462_2p0_common_mixed_rx_gain);
                INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core,
                               ar9462_2p0_baseband_core_mix_rxgain);
                INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
@@ -701,12 +773,12 @@ static void ar9003_rx_gain_table_mode3(struct ath_hw *ah)
 {
        if (AR_SREV_9462_21(ah)) {
                INIT_INI_ARRAY(&ah->iniModesRxGain,
-                              ar9462_2p1_common_5g_xlna_only_rx_gain);
+                              ar9462_2p1_common_5g_xlna_only_rxgain);
                INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
                               ar9462_2p1_baseband_postamble_5g_xlna);
        } else if (AR_SREV_9462_20(ah)) {
                INIT_INI_ARRAY(&ah->iniModesRxGain,
-                              ar9462_2p0_5g_xlna_only_rxgain);
+                              ar9462_2p0_common_5g_xlna_only_rxgain);
                INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
                               ar9462_2p0_baseband_postamble_5g_xlna);
        }
@@ -750,6 +822,9 @@ static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
 static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
                                         bool power_off)
 {
+       unsigned int i;
+       struct ar5416IniArray *array;
+
        /*
         * Increase L1 Entry Latency. Some WB222 boards don't have
         * this change in eeprom/OTP.
@@ -775,18 +850,13 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
         * Configire PCIE after Ini init. SERDES values now come from ini file
         * This enables PCIe low power mode.
         */
-       if (ah->config.pcieSerDesWrite) {
-               unsigned int i;
-               struct ar5416IniArray *array;
+       array = power_off ? &ah->iniPcieSerdes :
+               &ah->iniPcieSerdesLowPower;
 
-               array = power_off ? &ah->iniPcieSerdes :
-                                   &ah->iniPcieSerdesLowPower;
-
-               for (i = 0; i < array->ia_rows; i++) {
-                       REG_WRITE(ah,
-                                 INI_RA(array, i, 0),
-                                 INI_RA(array, i, 1));
-               }
+       for (i = 0; i < array->ia_rows; i++) {
+               REG_WRITE(ah,
+                         INI_RA(array, i, 0),
+                         INI_RA(array, i, 1));
        }
 }
 
index d39b79f5e841ada25c0e1bf435e7c7fd926c15ea..39b71b3d6919da5e59fcaa772f53aaf007ba870f 100644 (file)
@@ -641,11 +641,12 @@ static void ar9003_hw_override_ini(struct ath_hw *ah)
                else
                        ah->enabled_cals &= ~TX_IQ_CAL;
 
-               if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
-                       ah->enabled_cals |= TX_CL_CAL;
-               else
-                       ah->enabled_cals &= ~TX_CL_CAL;
        }
+
+       if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
+               ah->enabled_cals |= TX_CL_CAL;
+       else
+               ah->enabled_cals &= ~TX_CL_CAL;
 }
 
 static void ar9003_hw_prog_ini(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
new file mode 100644 (file)
index 0000000..81c88dd
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+ * 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 <linux/export.h>
+#include "ath9k.h"
+#include "reg.h"
+#include "hw-ops.h"
+
+const char *ath9k_hw_wow_event_to_string(u32 wow_event)
+{
+       if (wow_event & AH_WOW_MAGIC_PATTERN_EN)
+               return "Magic pattern";
+       if (wow_event & AH_WOW_USER_PATTERN_EN)
+               return "User pattern";
+       if (wow_event & AH_WOW_LINK_CHANGE)
+               return "Link change";
+       if (wow_event & AH_WOW_BEACON_MISS)
+               return "Beacon miss";
+
+       return  "unknown reason";
+}
+EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
+
+static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+
+       /* set rx disable bit */
+       REG_WRITE(ah, AR_CR, AR_CR_RXD);
+
+       if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
+               ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
+                       REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
+               return;
+       }
+
+       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
+}
+
+static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN];
+       u32 ctl[13] = {0};
+       u32 data_word[KAL_NUM_DATA_WORDS];
+       u8 i;
+       u32 wow_ka_data_word0;
+
+       memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
+       memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
+
+       /* set the transmit buffer */
+       ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
+       ctl[1] = 0;
+       ctl[3] = 0xb;   /* OFDM_6M hardware value for this rate */
+       ctl[4] = 0;
+       ctl[7] = (ah->txchainmask) << 2;
+       ctl[2] = 0xf << 16; /* tx_tries 0 */
+
+       for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
+               REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
+
+       REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
+
+       data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
+                      (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
+       data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
+                      (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
+       data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) |
+                      (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
+       data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) |
+                      (sta_mac_addr[3] << 8) | (sta_mac_addr[2]);
+       data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
+                      (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
+       data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
+
+       if (AR_SREV_9462_20(ah)) {
+               /* AR9462 2.0 has an extra descriptor word (time based
+                * discard) compared to other chips */
+               REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
+               wow_ka_data_word0 = AR_WOW_TXBUF(13);
+       } else {
+               wow_ka_data_word0 = AR_WOW_TXBUF(12);
+       }
+
+       for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
+               REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
+
+}
+
+void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
+                               u8 *user_mask, int pattern_count,
+                               int pattern_len)
+{
+       int i;
+       u32 pattern_val, mask_val;
+       u32 set, clr;
+
+       /* FIXME: should check count by querying the hardware capability */
+       if (pattern_count >= MAX_NUM_PATTERN)
+               return;
+
+       REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
+
+       /* set the registers for pattern */
+       for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
+               memcpy(&pattern_val, user_pattern, 4);
+               REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
+                         pattern_val);
+               user_pattern += 4;
+       }
+
+       /* set the registers for mask */
+       for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
+               memcpy(&mask_val, user_mask, 4);
+               REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
+               user_mask += 4;
+       }
+
+       /* set the pattern length to be matched
+        *
+        * AR_WOW_LENGTH1_REG1
+        * bit 31:24 pattern 0 length
+        * bit 23:16 pattern 1 length
+        * bit 15:8 pattern 2 length
+        * bit 7:0 pattern 3 length
+        *
+        * AR_WOW_LENGTH1_REG2
+        * bit 31:24 pattern 4 length
+        * bit 23:16 pattern 5 length
+        * bit 15:8 pattern 6 length
+        * bit 7:0 pattern 7 length
+        *
+        * the below logic writes out the new
+        * pattern length for the corresponding
+        * pattern_count, while masking out the
+        * other fields
+        */
+
+       ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
+
+       if (pattern_count < 4) {
+               /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
+               set = (pattern_len & AR_WOW_LENGTH_MAX) <<
+                      AR_WOW_LEN1_SHIFT(pattern_count);
+               clr = AR_WOW_LENGTH1_MASK(pattern_count);
+               REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
+       } else {
+               /* Pattern 4-7 uses AR_WOW_LENGTH2 register */
+               set = (pattern_len & AR_WOW_LENGTH_MAX) <<
+                      AR_WOW_LEN2_SHIFT(pattern_count);
+               clr = AR_WOW_LENGTH2_MASK(pattern_count);
+               REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
+       }
+
+}
+EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
+
+u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
+{
+       u32 wow_status = 0;
+       u32 val = 0, rval;
+
+       /*
+        * read the WoW status register to know
+        * the wakeup reason
+        */
+       rval = REG_READ(ah, AR_WOW_PATTERN);
+       val = AR_WOW_STATUS(rval);
+
+       /*
+        * mask only the WoW events that we have enabled. Sometimes
+        * we have spurious WoW events from the AR_WOW_PATTERN
+        * register. This mask will clean it up.
+        */
+
+       val &= ah->wow_event_mask;
+
+       if (val) {
+               if (val & AR_WOW_MAGIC_PAT_FOUND)
+                       wow_status |= AH_WOW_MAGIC_PATTERN_EN;
+               if (AR_WOW_PATTERN_FOUND(val))
+                       wow_status |= AH_WOW_USER_PATTERN_EN;
+               if (val & AR_WOW_KEEP_ALIVE_FAIL)
+                       wow_status |= AH_WOW_LINK_CHANGE;
+               if (val & AR_WOW_BEACON_FAIL)
+                       wow_status |= AH_WOW_BEACON_MISS;
+       }
+
+       /*
+        * set and clear WOW_PME_CLEAR registers for the chip to
+        * generate next wow signal.
+        * disable D3 before accessing other registers ?
+        */
+
+       /* do we need to check the bit value 0x01000000 (7-10) ?? */
+       REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR,
+               AR_PMCTRL_PWR_STATE_D1D3);
+
+       /*
+        * clear all events
+        */
+       REG_WRITE(ah, AR_WOW_PATTERN,
+                 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
+
+       /*
+        * restore the beacon threshold to init value
+        */
+       REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
+
+       /*
+        * Restore the way the PCI-E reset, Power-On-Reset, external
+        * PCIE_POR_SHORT pins are tied to its original value.
+        * Previously just before WoW sleep, we untie the PCI-E
+        * reset to our Chip's Power On Reset so that any PCI-E
+        * reset from the bus will not reset our chip
+        */
+       if (ah->is_pciexpress)
+               ath9k_hw_configpcipowersave(ah, false);
+
+       ah->wow_event_mask = 0;
+
+       return wow_status;
+}
+EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
+
+void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
+{
+       u32 wow_event_mask;
+       u32 set, clr;
+
+       /*
+        * wow_event_mask is a mask to the AR_WOW_PATTERN register to
+        * indicate which WoW events we have enabled. The WoW events
+        * are from the 'pattern_enable' in this function and
+        * 'pattern_count' of ath9k_hw_wow_apply_pattern()
+        */
+       wow_event_mask = ah->wow_event_mask;
+
+       /*
+        * Untie Power-on-Reset from the PCI-E-Reset. When we are in
+        * WOW sleep, we do want the Reset from the PCI-E to disturb
+        * our hw state
+        */
+       if (ah->is_pciexpress) {
+               /*
+                * we need to untie the internal POR (power-on-reset)
+                * to the external PCI-E reset. We also need to tie
+                * the PCI-E Phy reset to the PCI-E reset.
+                */
+               set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
+               clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
+               REG_RMW(ah, AR_WA, set, clr);
+       }
+
+       /*
+        * set the power states appropriately and enable PME
+        */
+       set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
+             AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
+
+       /*
+        * set and clear WOW_PME_CLEAR registers for the chip
+        * to generate next wow signal.
+        */
+       REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
+       clr = AR_PMCTRL_WOW_PME_CLR;
+       REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
+
+       /*
+        * Setup for:
+        *      - beacon misses
+        *      - magic pattern
+        *      - keep alive timeout
+        *      - pattern matching
+        */
+
+       /*
+        * Program default values for pattern backoff, aifs/slot/KAL count,
+        * beacon miss timeout, KAL timeout, etc.
+        */
+       set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
+       REG_SET_BIT(ah, AR_WOW_PATTERN, set);
+
+       set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
+             AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
+             AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT);
+       REG_SET_BIT(ah, AR_WOW_COUNT, set);
+
+       if (pattern_enable & AH_WOW_BEACON_MISS)
+               set = AR_WOW_BEACON_TIMO;
+       /* We are not using beacon miss, program a large value */
+       else
+               set = AR_WOW_BEACON_TIMO_MAX;
+
+       REG_WRITE(ah, AR_WOW_BCN_TIMO, set);
+
+       /*
+        * Keep alive timo in ms except AR9280
+        */
+       if (!pattern_enable)
+               set = AR_WOW_KEEP_ALIVE_NEVER;
+       else
+               set = KAL_TIMEOUT * 32;
+
+       REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set);
+
+       /*
+        * Keep alive delay in us. based on 'power on clock',
+        * therefore in usec
+        */
+       set = KAL_DELAY * 1000;
+       REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set);
+
+       /*
+        * Create keep alive pattern to respond to beacons
+        */
+       ath9k_wow_create_keep_alive_pattern(ah);
+
+       /*
+        * Configure MAC WoW Registers
+        */
+       set = 0;
+       /* Send keep alive timeouts anyway */
+       clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
+
+       if (pattern_enable & AH_WOW_LINK_CHANGE)
+               wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
+       else
+               set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
+
+       set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
+       REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
+
+       /*
+        * we are relying on a bmiss failure. ensure we have
+        * enough threshold to prevent false positives
+        */
+       REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR,
+                     AR_WOW_BMISSTHRESHOLD);
+
+       set = 0;
+       clr = 0;
+
+       if (pattern_enable & AH_WOW_BEACON_MISS) {
+               set = AR_WOW_BEACON_FAIL_EN;
+               wow_event_mask |= AR_WOW_BEACON_FAIL;
+       } else {
+               clr = AR_WOW_BEACON_FAIL_EN;
+       }
+
+       REG_RMW(ah, AR_WOW_BCN_EN, set, clr);
+
+       set = 0;
+       clr = 0;
+       /*
+        * Enable the magic packet registers
+        */
+       if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
+               set = AR_WOW_MAGIC_EN;
+               wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
+       } else {
+               clr = AR_WOW_MAGIC_EN;
+       }
+       set |= AR_WOW_MAC_INTR_EN;
+       REG_RMW(ah, AR_WOW_PATTERN, set, clr);
+
+       REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
+                 AR_WOW_PATTERN_SUPPORTED);
+
+       /*
+        * Set the power states appropriately and enable PME
+        */
+       clr = 0;
+       set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
+             AR_PMCTRL_PWR_PM_CTRL_ENA;
+
+       clr = AR_PCIE_PM_CTRL_ENA;
+       REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
+
+       /*
+        * this is needed to prevent the chip waking up
+        * the host within 3-4 seconds with certain
+        * platform/BIOS. The fix is to enable
+        * D1 & D3 to match original definition and
+        * also match the OTP value. Anyway this
+        * is more related to SW WOW.
+        */
+       clr = AR_PMCTRL_PWR_STATE_D1D3;
+       REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
+
+       set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
+       REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
+
+       REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
+
+       /* to bring down WOW power low margin */
+       set = BIT(13);
+       REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
+       /* HW WoW */
+       clr = BIT(5);
+       REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
+
+       ath9k_hw_set_powermode_wow_sleep(ah);
+       ah->wow_event_mask = wow_event_mask;
+}
+EXPORT_SYMBOL(ath9k_hw_wow_enable);
index 25db9215985aa1519e0901cb698b312811d6dc91..7f22cb2a494113f8575c326bcf19405febc6d7d1 100644 (file)
 #ifndef INITVALS_9340_H
 #define INITVALS_9340_H
 
+#define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble
+
+#define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble
+
+#define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2
+
+#define ar9340Common_rx_gain_table_1p0 ar9300Common_rx_gain_table_2p2
+
+#define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2
+
+#define ar9340_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
+
 static const u32 ar9340_1p0_radio_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800},
@@ -100,8 +112,6 @@ static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = {
        {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
 };
 
-#define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2
-
 static const u32 ar9340_1p0_radio_core[][2] = {
        /* Addr      allmodes  */
        {0x00016000, 0x36db6db6},
@@ -215,16 +225,12 @@ static const u32 ar9340_1p0_radio_core_40M[][2] = {
        {0x0000824c, 0x0001e800},
 };
 
-#define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble
-
-#define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble
-
 static const u32 ar9340_1p0_baseband_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
        {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e},
        {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
-       {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+       {0x00009828, 0x06903081, 0x06903081, 0x09103881, 0x09103881},
        {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
        {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
        {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
@@ -340,9 +346,9 @@ static const u32 ar9340_1p0_baseband_core[][2] = {
        {0x0000a370, 0x00000000},
        {0x0000a390, 0x00000001},
        {0x0000a394, 0x00000444},
-       {0x0000a398, 0x001f0e0f},
-       {0x0000a39c, 0x0075393f},
-       {0x0000a3a0, 0xb79f6427},
+       {0x0000a398, 0x00000000},
+       {0x0000a39c, 0x210d0401},
+       {0x0000a3a0, 0xab9a7144},
        {0x0000a3a4, 0x00000000},
        {0x0000a3a8, 0xaaaaaaaa},
        {0x0000a3ac, 0x3c466478},
@@ -714,266 +720,6 @@ static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = {
        {0x0000b2e8, 0xfffe0000, 0xfffe0000, 0xfffc0000, 0xfffc0000},
 };
 
-static const u32 ar9340Common_rx_gain_table_1p0[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x00010000},
-       {0x0000a004, 0x00030002},
-       {0x0000a008, 0x00050004},
-       {0x0000a00c, 0x00810080},
-       {0x0000a010, 0x00830082},
-       {0x0000a014, 0x01810180},
-       {0x0000a018, 0x01830182},
-       {0x0000a01c, 0x01850184},
-       {0x0000a020, 0x01890188},
-       {0x0000a024, 0x018b018a},
-       {0x0000a028, 0x018d018c},
-       {0x0000a02c, 0x01910190},
-       {0x0000a030, 0x01930192},
-       {0x0000a034, 0x01950194},
-       {0x0000a038, 0x038a0196},
-       {0x0000a03c, 0x038c038b},
-       {0x0000a040, 0x0390038d},
-       {0x0000a044, 0x03920391},
-       {0x0000a048, 0x03940393},
-       {0x0000a04c, 0x03960395},
-       {0x0000a050, 0x00000000},
-       {0x0000a054, 0x00000000},
-       {0x0000a058, 0x00000000},
-       {0x0000a05c, 0x00000000},
-       {0x0000a060, 0x00000000},
-       {0x0000a064, 0x00000000},
-       {0x0000a068, 0x00000000},
-       {0x0000a06c, 0x00000000},
-       {0x0000a070, 0x00000000},
-       {0x0000a074, 0x00000000},
-       {0x0000a078, 0x00000000},
-       {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x22222229},
-       {0x0000a084, 0x1d1d1d1d},
-       {0x0000a088, 0x1d1d1d1d},
-       {0x0000a08c, 0x1d1d1d1d},
-       {0x0000a090, 0x171d1d1d},
-       {0x0000a094, 0x11111717},
-       {0x0000a098, 0x00030311},
-       {0x0000a09c, 0x00000000},
-       {0x0000a0a0, 0x00000000},
-       {0x0000a0a4, 0x00000000},
-       {0x0000a0a8, 0x00000000},
-       {0x0000a0ac, 0x00000000},
-       {0x0000a0b0, 0x00000000},
-       {0x0000a0b4, 0x00000000},
-       {0x0000a0b8, 0x00000000},
-       {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x01000101},
-       {0x0000a0c8, 0x011e011f},
-       {0x0000a0cc, 0x011c011d},
-       {0x0000a0d0, 0x02030204},
-       {0x0000a0d4, 0x02010202},
-       {0x0000a0d8, 0x021f0200},
-       {0x0000a0dc, 0x0302021e},
-       {0x0000a0e0, 0x03000301},
-       {0x0000a0e4, 0x031e031f},
-       {0x0000a0e8, 0x0402031d},
-       {0x0000a0ec, 0x04000401},
-       {0x0000a0f0, 0x041e041f},
-       {0x0000a0f4, 0x0502041d},
-       {0x0000a0f8, 0x05000501},
-       {0x0000a0fc, 0x051e051f},
-       {0x0000a100, 0x06010602},
-       {0x0000a104, 0x061f0600},
-       {0x0000a108, 0x061d061e},
-       {0x0000a10c, 0x07020703},
-       {0x0000a110, 0x07000701},
-       {0x0000a114, 0x00000000},
-       {0x0000a118, 0x00000000},
-       {0x0000a11c, 0x00000000},
-       {0x0000a120, 0x00000000},
-       {0x0000a124, 0x00000000},
-       {0x0000a128, 0x00000000},
-       {0x0000a12c, 0x00000000},
-       {0x0000a130, 0x00000000},
-       {0x0000a134, 0x00000000},
-       {0x0000a138, 0x00000000},
-       {0x0000a13c, 0x00000000},
-       {0x0000a140, 0x001f0000},
-       {0x0000a144, 0x01000101},
-       {0x0000a148, 0x011e011f},
-       {0x0000a14c, 0x011c011d},
-       {0x0000a150, 0x02030204},
-       {0x0000a154, 0x02010202},
-       {0x0000a158, 0x021f0200},
-       {0x0000a15c, 0x0302021e},
-       {0x0000a160, 0x03000301},
-       {0x0000a164, 0x031e031f},
-       {0x0000a168, 0x0402031d},
-       {0x0000a16c, 0x04000401},
-       {0x0000a170, 0x041e041f},
-       {0x0000a174, 0x0502041d},
-       {0x0000a178, 0x05000501},
-       {0x0000a17c, 0x051e051f},
-       {0x0000a180, 0x06010602},
-       {0x0000a184, 0x061f0600},
-       {0x0000a188, 0x061d061e},
-       {0x0000a18c, 0x07020703},
-       {0x0000a190, 0x07000701},
-       {0x0000a194, 0x00000000},
-       {0x0000a198, 0x00000000},
-       {0x0000a19c, 0x00000000},
-       {0x0000a1a0, 0x00000000},
-       {0x0000a1a4, 0x00000000},
-       {0x0000a1a8, 0x00000000},
-       {0x0000a1ac, 0x00000000},
-       {0x0000a1b0, 0x00000000},
-       {0x0000a1b4, 0x00000000},
-       {0x0000a1b8, 0x00000000},
-       {0x0000a1bc, 0x00000000},
-       {0x0000a1c0, 0x00000000},
-       {0x0000a1c4, 0x00000000},
-       {0x0000a1c8, 0x00000000},
-       {0x0000a1cc, 0x00000000},
-       {0x0000a1d0, 0x00000000},
-       {0x0000a1d4, 0x00000000},
-       {0x0000a1d8, 0x00000000},
-       {0x0000a1dc, 0x00000000},
-       {0x0000a1e0, 0x00000000},
-       {0x0000a1e4, 0x00000000},
-       {0x0000a1e8, 0x00000000},
-       {0x0000a1ec, 0x00000000},
-       {0x0000a1f0, 0x00000396},
-       {0x0000a1f4, 0x00000396},
-       {0x0000a1f8, 0x00000396},
-       {0x0000a1fc, 0x00000196},
-       {0x0000b000, 0x00010000},
-       {0x0000b004, 0x00030002},
-       {0x0000b008, 0x00050004},
-       {0x0000b00c, 0x00810080},
-       {0x0000b010, 0x00830082},
-       {0x0000b014, 0x01810180},
-       {0x0000b018, 0x01830182},
-       {0x0000b01c, 0x01850184},
-       {0x0000b020, 0x02810280},
-       {0x0000b024, 0x02830282},
-       {0x0000b028, 0x02850284},
-       {0x0000b02c, 0x02890288},
-       {0x0000b030, 0x028b028a},
-       {0x0000b034, 0x0388028c},
-       {0x0000b038, 0x038a0389},
-       {0x0000b03c, 0x038c038b},
-       {0x0000b040, 0x0390038d},
-       {0x0000b044, 0x03920391},
-       {0x0000b048, 0x03940393},
-       {0x0000b04c, 0x03960395},
-       {0x0000b050, 0x00000000},
-       {0x0000b054, 0x00000000},
-       {0x0000b058, 0x00000000},
-       {0x0000b05c, 0x00000000},
-       {0x0000b060, 0x00000000},
-       {0x0000b064, 0x00000000},
-       {0x0000b068, 0x00000000},
-       {0x0000b06c, 0x00000000},
-       {0x0000b070, 0x00000000},
-       {0x0000b074, 0x00000000},
-       {0x0000b078, 0x00000000},
-       {0x0000b07c, 0x00000000},
-       {0x0000b080, 0x23232323},
-       {0x0000b084, 0x21232323},
-       {0x0000b088, 0x19191c1e},
-       {0x0000b08c, 0x12141417},
-       {0x0000b090, 0x07070e0e},
-       {0x0000b094, 0x03030305},
-       {0x0000b098, 0x00000003},
-       {0x0000b09c, 0x00000000},
-       {0x0000b0a0, 0x00000000},
-       {0x0000b0a4, 0x00000000},
-       {0x0000b0a8, 0x00000000},
-       {0x0000b0ac, 0x00000000},
-       {0x0000b0b0, 0x00000000},
-       {0x0000b0b4, 0x00000000},
-       {0x0000b0b8, 0x00000000},
-       {0x0000b0bc, 0x00000000},
-       {0x0000b0c0, 0x003f0020},
-       {0x0000b0c4, 0x00400041},
-       {0x0000b0c8, 0x0140005f},
-       {0x0000b0cc, 0x0160015f},
-       {0x0000b0d0, 0x017e017f},
-       {0x0000b0d4, 0x02410242},
-       {0x0000b0d8, 0x025f0240},
-       {0x0000b0dc, 0x027f0260},
-       {0x0000b0e0, 0x0341027e},
-       {0x0000b0e4, 0x035f0340},
-       {0x0000b0e8, 0x037f0360},
-       {0x0000b0ec, 0x04400441},
-       {0x0000b0f0, 0x0460045f},
-       {0x0000b0f4, 0x0541047f},
-       {0x0000b0f8, 0x055f0540},
-       {0x0000b0fc, 0x057f0560},
-       {0x0000b100, 0x06400641},
-       {0x0000b104, 0x0660065f},
-       {0x0000b108, 0x067e067f},
-       {0x0000b10c, 0x07410742},
-       {0x0000b110, 0x075f0740},
-       {0x0000b114, 0x077f0760},
-       {0x0000b118, 0x07800781},
-       {0x0000b11c, 0x07a0079f},
-       {0x0000b120, 0x07c107bf},
-       {0x0000b124, 0x000007c0},
-       {0x0000b128, 0x00000000},
-       {0x0000b12c, 0x00000000},
-       {0x0000b130, 0x00000000},
-       {0x0000b134, 0x00000000},
-       {0x0000b138, 0x00000000},
-       {0x0000b13c, 0x00000000},
-       {0x0000b140, 0x003f0020},
-       {0x0000b144, 0x00400041},
-       {0x0000b148, 0x0140005f},
-       {0x0000b14c, 0x0160015f},
-       {0x0000b150, 0x017e017f},
-       {0x0000b154, 0x02410242},
-       {0x0000b158, 0x025f0240},
-       {0x0000b15c, 0x027f0260},
-       {0x0000b160, 0x0341027e},
-       {0x0000b164, 0x035f0340},
-       {0x0000b168, 0x037f0360},
-       {0x0000b16c, 0x04400441},
-       {0x0000b170, 0x0460045f},
-       {0x0000b174, 0x0541047f},
-       {0x0000b178, 0x055f0540},
-       {0x0000b17c, 0x057f0560},
-       {0x0000b180, 0x06400641},
-       {0x0000b184, 0x0660065f},
-       {0x0000b188, 0x067e067f},
-       {0x0000b18c, 0x07410742},
-       {0x0000b190, 0x075f0740},
-       {0x0000b194, 0x077f0760},
-       {0x0000b198, 0x07800781},
-       {0x0000b19c, 0x07a0079f},
-       {0x0000b1a0, 0x07c107bf},
-       {0x0000b1a4, 0x000007c0},
-       {0x0000b1a8, 0x00000000},
-       {0x0000b1ac, 0x00000000},
-       {0x0000b1b0, 0x00000000},
-       {0x0000b1b4, 0x00000000},
-       {0x0000b1b8, 0x00000000},
-       {0x0000b1bc, 0x00000000},
-       {0x0000b1c0, 0x00000000},
-       {0x0000b1c4, 0x00000000},
-       {0x0000b1c8, 0x00000000},
-       {0x0000b1cc, 0x00000000},
-       {0x0000b1d0, 0x00000000},
-       {0x0000b1d4, 0x00000000},
-       {0x0000b1d8, 0x00000000},
-       {0x0000b1dc, 0x00000000},
-       {0x0000b1e0, 0x00000000},
-       {0x0000b1e4, 0x00000000},
-       {0x0000b1e8, 0x00000000},
-       {0x0000b1ec, 0x00000000},
-       {0x0000b1f0, 0x00000396},
-       {0x0000b1f4, 0x00000396},
-       {0x0000b1f8, 0x00000396},
-       {0x0000b1fc, 0x00000196},
-};
-
 static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
@@ -1437,8 +1183,6 @@ static const u32 ar9340_1p0_mac_core[][2] = {
        {0x000083d0, 0x000101ff},
 };
 
-#define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2
-
 static const u32 ar9340_1p0_soc_preamble[][2] = {
        /* Addr      allmodes  */
        {0x00007008, 0x00000000},
@@ -1447,4 +1191,106 @@ static const u32 ar9340_1p0_soc_preamble[][2] = {
        {0x00007038, 0x000004c2},
 };
 
+static const u32 ar9340_cus227_tx_gain_table_1p0[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+       {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+       {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400},
+       {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
+       {0x0000a520, 0x2c022220, 0x2c022220, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x30022222, 0x30022222, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x35022225, 0x35022225, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x3b02222a, 0x3b02222a, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x3f02222c, 0x3f02222c, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
+       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
+       {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x61024a6c, 0x61024a6c, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x66026a6c, 0x66026a6c, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x7002708c, 0x7002708c, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x7302b08a, 0x7302b08a, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+       {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+       {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400},
+       {0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
+       {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
+       {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
+       {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
+       {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
+       {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
+       {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
+       {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
+       {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
+       {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
+       {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
+       {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+       {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+       {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
+       {0x00016048, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266},
+       {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015},
+       {0x00016288, 0x30318000, 0x30318000, 0x00318000, 0x00318000},
+       {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
+       {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266},
+       {0x0000a3a4, 0x00000011, 0x00000011, 0x00000011, 0x00000011},
+       {0x0000a3a8, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c},
+       {0x0000a3ac, 0x30303030, 0x30303030, 0x30303030, 0x30303030},
+};
+
 #endif /* INITVALS_9340_H */
index 092b9d412e7fd7f70b5f1996b94a66703325f830..739094384369c863390d567df5ecfb8a801af8be 100644 (file)
@@ -20,7 +20,7 @@
 
 /* AR9462 2.0 */
 
-static const u32 ar9462_modes_fast_clock_2p0[][3] = {
+static const u32 ar9462_2p0_modes_fast_clock[][3] = {
        /* Addr      5G_HT20     5G_HT40   */
        {0x00001030, 0x00000268, 0x000004d0},
        {0x00001070, 0x0000018c, 0x00000318},
@@ -33,13 +33,6 @@ static const u32 ar9462_modes_fast_clock_2p0[][3] = {
        {0x0000a254, 0x00000898, 0x00001130},
 };
 
-static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = {
-       /* Addr      allmodes  */
-       {0x00018c00, 0x18253ede},
-       {0x00018c04, 0x000801d8},
-       {0x00018c08, 0x0003780c},
-};
-
 static const u32 ar9462_2p0_baseband_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
@@ -99,7 +92,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
        {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
 };
 
-static const u32 ar9462_common_rx_gain_table_2p0[][2] = {
+static const u32 ar9462_2p0_common_rx_gain[][2] = {
        /* Addr      allmodes  */
        {0x0000a000, 0x00010000},
        {0x0000a004, 0x00030002},
@@ -359,20 +352,13 @@ static const u32 ar9462_common_rx_gain_table_2p0[][2] = {
        {0x0000b1fc, 0x00000196},
 };
 
-static const u32 ar9462_pciephy_clkreq_disable_L1_2p0[][2] = {
+static const u32 ar9462_2p0_pciephy_clkreq_disable_L1[][2] = {
        /* Addr      allmodes  */
        {0x00018c00, 0x18213ede},
        {0x00018c04, 0x000801d8},
        {0x00018c08, 0x0003780c},
 };
 
-static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
-       /* Addr      allmodes  */
-       {0x00018c00, 0x18212ede},
-       {0x00018c04, 0x000801d8},
-       {0x00018c08, 0x0003780c},
-};
-
 static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
@@ -380,7 +366,7 @@ static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
        {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
 };
 
-static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = {
+static const u32 ar9462_2p0_common_wo_xlna_rx_gain[][2] = {
        /* Addr      allmodes  */
        {0x0000a000, 0x00010000},
        {0x0000a004, 0x00030002},
@@ -647,7 +633,7 @@ static const u32 ar9462_2p0_baseband_core_txfir_coeff_japan_2484[][2] = {
        {0x0000a3a0, 0xca9228ee},
 };
 
-static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = {
+static const u32 ar9462_2p0_modes_low_ob_db_tx_gain[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
        {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
@@ -879,7 +865,7 @@ static const u32 ar9462_2p0_radio_postamble[][5] = {
        {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
 };
 
-static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = {
+static const u32 ar9462_2p0_modes_mix_ob_db_tx_gain[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
        {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
@@ -942,7 +928,7 @@ static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = {
        {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
 };
 
-static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
+static const u32 ar9462_2p0_modes_high_ob_db_tx_gain[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
        {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
@@ -1252,7 +1238,7 @@ static const u32 ar9462_2p0_mac_postamble[][5] = {
        {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
 };
 
-static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = {
+static const u32 ar9462_2p0_common_mixed_rx_gain[][2] = {
        /* Addr      allmodes  */
        {0x0000a000, 0x00010000},
        {0x0000a004, 0x00030002},
@@ -1517,7 +1503,7 @@ static const u32 ar9462_2p0_baseband_postamble_5g_xlna[][5] = {
        {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
 };
 
-static const u32 ar9462_2p0_5g_xlna_only_rxgain[][2] = {
+static const u32 ar9462_2p0_common_5g_xlna_only_rxgain[][2] = {
        /* Addr      allmodes  */
        {0x0000a000, 0x00010000},
        {0x0000a004, 0x00030002},
index 57fc5f459d0aa6a40719407b8c287ac7f3786d00..dc3adda46e8b92700ee1c274ba734fc2c4ec7a4f 100644 (file)
 
 /* AR9462 2.1 */
 
+#define ar9462_2p1_mac_postamble ar9462_2p0_mac_postamble
+
+#define ar9462_2p1_baseband_core ar9462_2p0_baseband_core
+
+#define ar9462_2p1_radio_core ar9462_2p0_radio_core
+
+#define ar9462_2p1_radio_postamble ar9462_2p0_radio_postamble
+
+#define ar9462_2p1_soc_postamble ar9462_2p0_soc_postamble
+
+#define ar9462_2p1_radio_postamble_sys2ant ar9462_2p0_radio_postamble_sys2ant
+
+#define ar9462_2p1_common_rx_gain ar9462_2p0_common_rx_gain
+
+#define ar9462_2p1_common_mixed_rx_gain ar9462_2p0_common_mixed_rx_gain
+
+#define ar9462_2p1_common_5g_xlna_only_rxgain ar9462_2p0_common_5g_xlna_only_rxgain
+
+#define ar9462_2p1_baseband_core_mix_rxgain ar9462_2p0_baseband_core_mix_rxgain
+
+#define ar9462_2p1_baseband_postamble_mix_rxgain ar9462_2p0_baseband_postamble_mix_rxgain
+
+#define ar9462_2p1_baseband_postamble_5g_xlna ar9462_2p0_baseband_postamble_5g_xlna
+
+#define ar9462_2p1_common_wo_xlna_rx_gain ar9462_2p0_common_wo_xlna_rx_gain
+
+#define ar9462_2p1_modes_low_ob_db_tx_gain ar9462_2p0_modes_low_ob_db_tx_gain
+
+#define ar9462_2p1_modes_high_ob_db_tx_gain ar9462_2p0_modes_high_ob_db_tx_gain
+
+#define ar9462_2p1_modes_mix_ob_db_tx_gain ar9462_2p0_modes_mix_ob_db_tx_gain
+
+#define ar9462_2p1_modes_fast_clock ar9462_2p0_modes_fast_clock
+
+#define ar9462_2p1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
+
+#define ar9462_2p1_pciephy_clkreq_disable_L1 ar9462_2p0_pciephy_clkreq_disable_L1
+
 static const u32 ar9462_2p1_mac_core[][2] = {
        /* Addr      allmodes  */
        {0x00000008, 0x00000000},
@@ -183,168 +221,6 @@ static const u32 ar9462_2p1_mac_core[][2] = {
        {0x000083d0, 0x000301ff},
 };
 
-static const u32 ar9462_2p1_mac_postamble[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
-       {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
-       {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
-       {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
-       {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
-       {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
-       {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
-       {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
-};
-
-static const u32 ar9462_2p1_baseband_core[][2] = {
-       /* Addr      allmodes  */
-       {0x00009800, 0xafe68e30},
-       {0x00009804, 0xfd14e000},
-       {0x00009808, 0x9c0a9f6b},
-       {0x0000980c, 0x04900000},
-       {0x00009814, 0x9280c00a},
-       {0x00009818, 0x00000000},
-       {0x0000981c, 0x00020028},
-       {0x00009834, 0x6400a290},
-       {0x00009838, 0x0108ecff},
-       {0x0000983c, 0x0d000600},
-       {0x00009880, 0x201fff00},
-       {0x00009884, 0x00001042},
-       {0x000098a4, 0x00200400},
-       {0x000098b0, 0x32440bbe},
-       {0x000098d0, 0x004b6a8e},
-       {0x000098d4, 0x00000820},
-       {0x000098dc, 0x00000000},
-       {0x000098e4, 0x01ffffff},
-       {0x000098e8, 0x01ffffff},
-       {0x000098ec, 0x01ffffff},
-       {0x000098f0, 0x00000000},
-       {0x000098f4, 0x00000000},
-       {0x00009bf0, 0x80000000},
-       {0x00009c04, 0xff55ff55},
-       {0x00009c08, 0x0320ff55},
-       {0x00009c0c, 0x00000000},
-       {0x00009c10, 0x00000000},
-       {0x00009c14, 0x00046384},
-       {0x00009c18, 0x05b6b440},
-       {0x00009c1c, 0x00b6b440},
-       {0x00009d00, 0xc080a333},
-       {0x00009d04, 0x40206c10},
-       {0x00009d08, 0x009c4060},
-       {0x00009d0c, 0x9883800a},
-       {0x00009d10, 0x01834061},
-       {0x00009d14, 0x00c0040b},
-       {0x00009d18, 0x00000000},
-       {0x00009e08, 0x0038230c},
-       {0x00009e24, 0x990bb515},
-       {0x00009e28, 0x0c6f0000},
-       {0x00009e30, 0x06336f77},
-       {0x00009e34, 0x6af6532f},
-       {0x00009e38, 0x0cc80c00},
-       {0x00009e40, 0x15262820},
-       {0x00009e4c, 0x00001004},
-       {0x00009e50, 0x00ff03f1},
-       {0x00009e54, 0xe4c555c2},
-       {0x00009e58, 0xfd857722},
-       {0x00009e5c, 0xe9198724},
-       {0x00009fc0, 0x803e4788},
-       {0x00009fc4, 0x0001efb5},
-       {0x00009fcc, 0x40000014},
-       {0x00009fd0, 0x0a193b93},
-       {0x0000a20c, 0x00000000},
-       {0x0000a220, 0x00000000},
-       {0x0000a224, 0x00000000},
-       {0x0000a228, 0x10002310},
-       {0x0000a23c, 0x00000000},
-       {0x0000a244, 0x0c000000},
-       {0x0000a2a0, 0x00000001},
-       {0x0000a2c0, 0x00000001},
-       {0x0000a2c8, 0x00000000},
-       {0x0000a2cc, 0x18c43433},
-       {0x0000a2d4, 0x00000000},
-       {0x0000a2ec, 0x00000000},
-       {0x0000a2f0, 0x00000000},
-       {0x0000a2f4, 0x00000000},
-       {0x0000a2f8, 0x00000000},
-       {0x0000a344, 0x00000000},
-       {0x0000a34c, 0x00000000},
-       {0x0000a350, 0x0000a000},
-       {0x0000a364, 0x00000000},
-       {0x0000a370, 0x00000000},
-       {0x0000a390, 0x00000001},
-       {0x0000a394, 0x00000444},
-       {0x0000a398, 0x001f0e0f},
-       {0x0000a39c, 0x0075393f},
-       {0x0000a3a0, 0xb79f6427},
-       {0x0000a3c0, 0x20202020},
-       {0x0000a3c4, 0x22222220},
-       {0x0000a3c8, 0x20200020},
-       {0x0000a3cc, 0x20202020},
-       {0x0000a3d0, 0x20202020},
-       {0x0000a3d4, 0x20202020},
-       {0x0000a3d8, 0x20202020},
-       {0x0000a3dc, 0x20202020},
-       {0x0000a3e0, 0x20202020},
-       {0x0000a3e4, 0x20202020},
-       {0x0000a3e8, 0x20202020},
-       {0x0000a3ec, 0x20202020},
-       {0x0000a3f0, 0x00000000},
-       {0x0000a3f4, 0x00000006},
-       {0x0000a3f8, 0x0c9bd380},
-       {0x0000a3fc, 0x000f0f01},
-       {0x0000a400, 0x8fa91f01},
-       {0x0000a404, 0x00000000},
-       {0x0000a408, 0x0e79e5c6},
-       {0x0000a40c, 0x00820820},
-       {0x0000a414, 0x1ce739ce},
-       {0x0000a418, 0x2d001dce},
-       {0x0000a434, 0x00000000},
-       {0x0000a438, 0x00001801},
-       {0x0000a43c, 0x00100000},
-       {0x0000a444, 0x00000000},
-       {0x0000a448, 0x05000080},
-       {0x0000a44c, 0x00000001},
-       {0x0000a450, 0x00010000},
-       {0x0000a454, 0x07000000},
-       {0x0000a644, 0xbfad9d74},
-       {0x0000a648, 0x0048060a},
-       {0x0000a64c, 0x00002037},
-       {0x0000a670, 0x03020100},
-       {0x0000a674, 0x09080504},
-       {0x0000a678, 0x0d0c0b0a},
-       {0x0000a67c, 0x13121110},
-       {0x0000a680, 0x31301514},
-       {0x0000a684, 0x35343332},
-       {0x0000a688, 0x00000036},
-       {0x0000a690, 0x00000838},
-       {0x0000a6b0, 0x0000000a},
-       {0x0000a6b4, 0x00512c01},
-       {0x0000a7c0, 0x00000000},
-       {0x0000a7c4, 0xfffffffc},
-       {0x0000a7c8, 0x00000000},
-       {0x0000a7cc, 0x00000000},
-       {0x0000a7d0, 0x00000000},
-       {0x0000a7d4, 0x00000004},
-       {0x0000a7dc, 0x00000000},
-       {0x0000a7f0, 0x80000000},
-       {0x0000a8d0, 0x004b6a8e},
-       {0x0000a8d4, 0x00000820},
-       {0x0000a8dc, 0x00000000},
-       {0x0000a8f0, 0x00000000},
-       {0x0000a8f4, 0x00000000},
-       {0x0000abf0, 0x80000000},
-       {0x0000b2d0, 0x00000080},
-       {0x0000b2d4, 0x00000000},
-       {0x0000b2ec, 0x00000000},
-       {0x0000b2f0, 0x00000000},
-       {0x0000b2f4, 0x00000000},
-       {0x0000b2f8, 0x00000000},
-       {0x0000b408, 0x0e79e5c0},
-       {0x0000b40c, 0x00820820},
-       {0x0000b420, 0x00000000},
-       {0x0000b6b0, 0x0000000a},
-       {0x0000b6b4, 0x00000001},
-};
-
 static const u32 ar9462_2p1_baseband_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
@@ -404,72 +280,6 @@ static const u32 ar9462_2p1_baseband_postamble[][5] = {
        {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
 };
 
-static const u32 ar9462_2p1_radio_core[][2] = {
-       /* Addr      allmodes  */
-       {0x00016000, 0x36db6db6},
-       {0x00016004, 0x6db6db40},
-       {0x00016008, 0x73f00000},
-       {0x0001600c, 0x00000000},
-       {0x00016010, 0x6d820001},
-       {0x00016040, 0x7f80fff8},
-       {0x0001604c, 0x2699e04f},
-       {0x00016050, 0x6db6db6c},
-       {0x00016058, 0x6c200000},
-       {0x00016080, 0x000c0000},
-       {0x00016084, 0x9a68048c},
-       {0x00016088, 0x54214514},
-       {0x0001608c, 0x1203040b},
-       {0x00016090, 0x24926490},
-       {0x00016098, 0xd2888888},
-       {0x000160a0, 0x0a108ffe},
-       {0x000160a4, 0x812fc491},
-       {0x000160a8, 0x423c8000},
-       {0x000160b4, 0x92000000},
-       {0x000160b8, 0x0285dddc},
-       {0x000160bc, 0x02908888},
-       {0x000160c0, 0x00adb6d0},
-       {0x000160c4, 0x6db6db60},
-       {0x000160c8, 0x6db6db6c},
-       {0x000160cc, 0x0de6c1b0},
-       {0x00016100, 0x3fffbe04},
-       {0x00016104, 0xfff80000},
-       {0x00016108, 0x00200400},
-       {0x00016110, 0x00000000},
-       {0x00016144, 0x02084080},
-       {0x00016148, 0x000080c0},
-       {0x00016280, 0x050a0001},
-       {0x00016284, 0x3d841418},
-       {0x00016288, 0x00000000},
-       {0x0001628c, 0xe3000000},
-       {0x00016290, 0xa1005080},
-       {0x00016294, 0x00000020},
-       {0x00016298, 0x54a82900},
-       {0x00016340, 0x121e4276},
-       {0x00016344, 0x00300000},
-       {0x00016400, 0x36db6db6},
-       {0x00016404, 0x6db6db40},
-       {0x00016408, 0x73f00000},
-       {0x0001640c, 0x00000000},
-       {0x00016410, 0x6c800001},
-       {0x00016440, 0x7f80fff8},
-       {0x0001644c, 0x4699e04f},
-       {0x00016450, 0x6db6db6c},
-       {0x00016500, 0x3fffbe04},
-       {0x00016504, 0xfff80000},
-       {0x00016508, 0x00200400},
-       {0x00016510, 0x00000000},
-       {0x00016544, 0x02084080},
-       {0x00016548, 0x000080c0},
-};
-
-static const u32 ar9462_2p1_radio_postamble[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
-       {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
-       {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
-       {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
-};
-
 static const u32 ar9462_2p1_soc_preamble[][2] = {
        /* Addr      allmodes  */
        {0x000040a4, 0x00a0c9c9},
@@ -478,1297 +288,4 @@ static const u32 ar9462_2p1_soc_preamble[][2] = {
        {0x00007038, 0x000004c2},
 };
 
-static const u32 ar9462_2p1_soc_postamble[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033},
-};
-
-static const u32 ar9462_2p1_radio_postamble_sys2ant[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
-       {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-       {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-};
-
-static const u32 ar9462_2p1_common_rx_gain[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x00010000},
-       {0x0000a004, 0x00030002},
-       {0x0000a008, 0x00050004},
-       {0x0000a00c, 0x00810080},
-       {0x0000a010, 0x00830082},
-       {0x0000a014, 0x01810180},
-       {0x0000a018, 0x01830182},
-       {0x0000a01c, 0x01850184},
-       {0x0000a020, 0x01890188},
-       {0x0000a024, 0x018b018a},
-       {0x0000a028, 0x018d018c},
-       {0x0000a02c, 0x01910190},
-       {0x0000a030, 0x01930192},
-       {0x0000a034, 0x01950194},
-       {0x0000a038, 0x038a0196},
-       {0x0000a03c, 0x038c038b},
-       {0x0000a040, 0x0390038d},
-       {0x0000a044, 0x03920391},
-       {0x0000a048, 0x03940393},
-       {0x0000a04c, 0x03960395},
-       {0x0000a050, 0x00000000},
-       {0x0000a054, 0x00000000},
-       {0x0000a058, 0x00000000},
-       {0x0000a05c, 0x00000000},
-       {0x0000a060, 0x00000000},
-       {0x0000a064, 0x00000000},
-       {0x0000a068, 0x00000000},
-       {0x0000a06c, 0x00000000},
-       {0x0000a070, 0x00000000},
-       {0x0000a074, 0x00000000},
-       {0x0000a078, 0x00000000},
-       {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x22222229},
-       {0x0000a084, 0x1d1d1d1d},
-       {0x0000a088, 0x1d1d1d1d},
-       {0x0000a08c, 0x1d1d1d1d},
-       {0x0000a090, 0x171d1d1d},
-       {0x0000a094, 0x11111717},
-       {0x0000a098, 0x00030311},
-       {0x0000a09c, 0x00000000},
-       {0x0000a0a0, 0x00000000},
-       {0x0000a0a4, 0x00000000},
-       {0x0000a0a8, 0x00000000},
-       {0x0000a0ac, 0x00000000},
-       {0x0000a0b0, 0x00000000},
-       {0x0000a0b4, 0x00000000},
-       {0x0000a0b8, 0x00000000},
-       {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x01000101},
-       {0x0000a0c8, 0x011e011f},
-       {0x0000a0cc, 0x011c011d},
-       {0x0000a0d0, 0x02030204},
-       {0x0000a0d4, 0x02010202},
-       {0x0000a0d8, 0x021f0200},
-       {0x0000a0dc, 0x0302021e},
-       {0x0000a0e0, 0x03000301},
-       {0x0000a0e4, 0x031e031f},
-       {0x0000a0e8, 0x0402031d},
-       {0x0000a0ec, 0x04000401},
-       {0x0000a0f0, 0x041e041f},
-       {0x0000a0f4, 0x0502041d},
-       {0x0000a0f8, 0x05000501},
-       {0x0000a0fc, 0x051e051f},
-       {0x0000a100, 0x06010602},
-       {0x0000a104, 0x061f0600},
-       {0x0000a108, 0x061d061e},
-       {0x0000a10c, 0x07020703},
-       {0x0000a110, 0x07000701},
-       {0x0000a114, 0x00000000},
-       {0x0000a118, 0x00000000},
-       {0x0000a11c, 0x00000000},
-       {0x0000a120, 0x00000000},
-       {0x0000a124, 0x00000000},
-       {0x0000a128, 0x00000000},
-       {0x0000a12c, 0x00000000},
-       {0x0000a130, 0x00000000},
-       {0x0000a134, 0x00000000},
-       {0x0000a138, 0x00000000},
-       {0x0000a13c, 0x00000000},
-       {0x0000a140, 0x001f0000},
-       {0x0000a144, 0x01000101},
-       {0x0000a148, 0x011e011f},
-       {0x0000a14c, 0x011c011d},
-       {0x0000a150, 0x02030204},
-       {0x0000a154, 0x02010202},
-       {0x0000a158, 0x021f0200},
-       {0x0000a15c, 0x0302021e},
-       {0x0000a160, 0x03000301},
-       {0x0000a164, 0x031e031f},
-       {0x0000a168, 0x0402031d},
-       {0x0000a16c, 0x04000401},
-       {0x0000a170, 0x041e041f},
-       {0x0000a174, 0x0502041d},
-       {0x0000a178, 0x05000501},
-       {0x0000a17c, 0x051e051f},
-       {0x0000a180, 0x06010602},
-       {0x0000a184, 0x061f0600},
-       {0x0000a188, 0x061d061e},
-       {0x0000a18c, 0x07020703},
-       {0x0000a190, 0x07000701},
-       {0x0000a194, 0x00000000},
-       {0x0000a198, 0x00000000},
-       {0x0000a19c, 0x00000000},
-       {0x0000a1a0, 0x00000000},
-       {0x0000a1a4, 0x00000000},
-       {0x0000a1a8, 0x00000000},
-       {0x0000a1ac, 0x00000000},
-       {0x0000a1b0, 0x00000000},
-       {0x0000a1b4, 0x00000000},
-       {0x0000a1b8, 0x00000000},
-       {0x0000a1bc, 0x00000000},
-       {0x0000a1c0, 0x00000000},
-       {0x0000a1c4, 0x00000000},
-       {0x0000a1c8, 0x00000000},
-       {0x0000a1cc, 0x00000000},
-       {0x0000a1d0, 0x00000000},
-       {0x0000a1d4, 0x00000000},
-       {0x0000a1d8, 0x00000000},
-       {0x0000a1dc, 0x00000000},
-       {0x0000a1e0, 0x00000000},
-       {0x0000a1e4, 0x00000000},
-       {0x0000a1e8, 0x00000000},
-       {0x0000a1ec, 0x00000000},
-       {0x0000a1f0, 0x00000396},
-       {0x0000a1f4, 0x00000396},
-       {0x0000a1f8, 0x00000396},
-       {0x0000a1fc, 0x00000196},
-       {0x0000b000, 0x00010000},
-       {0x0000b004, 0x00030002},
-       {0x0000b008, 0x00050004},
-       {0x0000b00c, 0x00810080},
-       {0x0000b010, 0x00830082},
-       {0x0000b014, 0x01810180},
-       {0x0000b018, 0x01830182},
-       {0x0000b01c, 0x01850184},
-       {0x0000b020, 0x02810280},
-       {0x0000b024, 0x02830282},
-       {0x0000b028, 0x02850284},
-       {0x0000b02c, 0x02890288},
-       {0x0000b030, 0x028b028a},
-       {0x0000b034, 0x0388028c},
-       {0x0000b038, 0x038a0389},
-       {0x0000b03c, 0x038c038b},
-       {0x0000b040, 0x0390038d},
-       {0x0000b044, 0x03920391},
-       {0x0000b048, 0x03940393},
-       {0x0000b04c, 0x03960395},
-       {0x0000b050, 0x00000000},
-       {0x0000b054, 0x00000000},
-       {0x0000b058, 0x00000000},
-       {0x0000b05c, 0x00000000},
-       {0x0000b060, 0x00000000},
-       {0x0000b064, 0x00000000},
-       {0x0000b068, 0x00000000},
-       {0x0000b06c, 0x00000000},
-       {0x0000b070, 0x00000000},
-       {0x0000b074, 0x00000000},
-       {0x0000b078, 0x00000000},
-       {0x0000b07c, 0x00000000},
-       {0x0000b080, 0x2a2d2f32},
-       {0x0000b084, 0x21232328},
-       {0x0000b088, 0x19191c1e},
-       {0x0000b08c, 0x12141417},
-       {0x0000b090, 0x07070e0e},
-       {0x0000b094, 0x03030305},
-       {0x0000b098, 0x00000003},
-       {0x0000b09c, 0x00000000},
-       {0x0000b0a0, 0x00000000},
-       {0x0000b0a4, 0x00000000},
-       {0x0000b0a8, 0x00000000},
-       {0x0000b0ac, 0x00000000},
-       {0x0000b0b0, 0x00000000},
-       {0x0000b0b4, 0x00000000},
-       {0x0000b0b8, 0x00000000},
-       {0x0000b0bc, 0x00000000},
-       {0x0000b0c0, 0x003f0020},
-       {0x0000b0c4, 0x00400041},
-       {0x0000b0c8, 0x0140005f},
-       {0x0000b0cc, 0x0160015f},
-       {0x0000b0d0, 0x017e017f},
-       {0x0000b0d4, 0x02410242},
-       {0x0000b0d8, 0x025f0240},
-       {0x0000b0dc, 0x027f0260},
-       {0x0000b0e0, 0x0341027e},
-       {0x0000b0e4, 0x035f0340},
-       {0x0000b0e8, 0x037f0360},
-       {0x0000b0ec, 0x04400441},
-       {0x0000b0f0, 0x0460045f},
-       {0x0000b0f4, 0x0541047f},
-       {0x0000b0f8, 0x055f0540},
-       {0x0000b0fc, 0x057f0560},
-       {0x0000b100, 0x06400641},
-       {0x0000b104, 0x0660065f},
-       {0x0000b108, 0x067e067f},
-       {0x0000b10c, 0x07410742},
-       {0x0000b110, 0x075f0740},
-       {0x0000b114, 0x077f0760},
-       {0x0000b118, 0x07800781},
-       {0x0000b11c, 0x07a0079f},
-       {0x0000b120, 0x07c107bf},
-       {0x0000b124, 0x000007c0},
-       {0x0000b128, 0x00000000},
-       {0x0000b12c, 0x00000000},
-       {0x0000b130, 0x00000000},
-       {0x0000b134, 0x00000000},
-       {0x0000b138, 0x00000000},
-       {0x0000b13c, 0x00000000},
-       {0x0000b140, 0x003f0020},
-       {0x0000b144, 0x00400041},
-       {0x0000b148, 0x0140005f},
-       {0x0000b14c, 0x0160015f},
-       {0x0000b150, 0x017e017f},
-       {0x0000b154, 0x02410242},
-       {0x0000b158, 0x025f0240},
-       {0x0000b15c, 0x027f0260},
-       {0x0000b160, 0x0341027e},
-       {0x0000b164, 0x035f0340},
-       {0x0000b168, 0x037f0360},
-       {0x0000b16c, 0x04400441},
-       {0x0000b170, 0x0460045f},
-       {0x0000b174, 0x0541047f},
-       {0x0000b178, 0x055f0540},
-       {0x0000b17c, 0x057f0560},
-       {0x0000b180, 0x06400641},
-       {0x0000b184, 0x0660065f},
-       {0x0000b188, 0x067e067f},
-       {0x0000b18c, 0x07410742},
-       {0x0000b190, 0x075f0740},
-       {0x0000b194, 0x077f0760},
-       {0x0000b198, 0x07800781},
-       {0x0000b19c, 0x07a0079f},
-       {0x0000b1a0, 0x07c107bf},
-       {0x0000b1a4, 0x000007c0},
-       {0x0000b1a8, 0x00000000},
-       {0x0000b1ac, 0x00000000},
-       {0x0000b1b0, 0x00000000},
-       {0x0000b1b4, 0x00000000},
-       {0x0000b1b8, 0x00000000},
-       {0x0000b1bc, 0x00000000},
-       {0x0000b1c0, 0x00000000},
-       {0x0000b1c4, 0x00000000},
-       {0x0000b1c8, 0x00000000},
-       {0x0000b1cc, 0x00000000},
-       {0x0000b1d0, 0x00000000},
-       {0x0000b1d4, 0x00000000},
-       {0x0000b1d8, 0x00000000},
-       {0x0000b1dc, 0x00000000},
-       {0x0000b1e0, 0x00000000},
-       {0x0000b1e4, 0x00000000},
-       {0x0000b1e8, 0x00000000},
-       {0x0000b1ec, 0x00000000},
-       {0x0000b1f0, 0x00000396},
-       {0x0000b1f4, 0x00000396},
-       {0x0000b1f8, 0x00000396},
-       {0x0000b1fc, 0x00000196},
-};
-
-static const u32 ar9462_2p1_common_mixed_rx_gain[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x00010000},
-       {0x0000a004, 0x00030002},
-       {0x0000a008, 0x00050004},
-       {0x0000a00c, 0x00810080},
-       {0x0000a010, 0x00830082},
-       {0x0000a014, 0x01810180},
-       {0x0000a018, 0x01830182},
-       {0x0000a01c, 0x01850184},
-       {0x0000a020, 0x01890188},
-       {0x0000a024, 0x018b018a},
-       {0x0000a028, 0x018d018c},
-       {0x0000a02c, 0x03820190},
-       {0x0000a030, 0x03840383},
-       {0x0000a034, 0x03880385},
-       {0x0000a038, 0x038a0389},
-       {0x0000a03c, 0x038c038b},
-       {0x0000a040, 0x0390038d},
-       {0x0000a044, 0x03920391},
-       {0x0000a048, 0x03940393},
-       {0x0000a04c, 0x03960395},
-       {0x0000a050, 0x00000000},
-       {0x0000a054, 0x00000000},
-       {0x0000a058, 0x00000000},
-       {0x0000a05c, 0x00000000},
-       {0x0000a060, 0x00000000},
-       {0x0000a064, 0x00000000},
-       {0x0000a068, 0x00000000},
-       {0x0000a06c, 0x00000000},
-       {0x0000a070, 0x00000000},
-       {0x0000a074, 0x00000000},
-       {0x0000a078, 0x00000000},
-       {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x29292929},
-       {0x0000a084, 0x29292929},
-       {0x0000a088, 0x29292929},
-       {0x0000a08c, 0x29292929},
-       {0x0000a090, 0x22292929},
-       {0x0000a094, 0x1d1d2222},
-       {0x0000a098, 0x0c111117},
-       {0x0000a09c, 0x00030303},
-       {0x0000a0a0, 0x00000000},
-       {0x0000a0a4, 0x00000000},
-       {0x0000a0a8, 0x00000000},
-       {0x0000a0ac, 0x00000000},
-       {0x0000a0b0, 0x00000000},
-       {0x0000a0b4, 0x00000000},
-       {0x0000a0b8, 0x00000000},
-       {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x01000101},
-       {0x0000a0c8, 0x011e011f},
-       {0x0000a0cc, 0x011c011d},
-       {0x0000a0d0, 0x02030204},
-       {0x0000a0d4, 0x02010202},
-       {0x0000a0d8, 0x021f0200},
-       {0x0000a0dc, 0x0302021e},
-       {0x0000a0e0, 0x03000301},
-       {0x0000a0e4, 0x031e031f},
-       {0x0000a0e8, 0x0402031d},
-       {0x0000a0ec, 0x04000401},
-       {0x0000a0f0, 0x041e041f},
-       {0x0000a0f4, 0x0502041d},
-       {0x0000a0f8, 0x05000501},
-       {0x0000a0fc, 0x051e051f},
-       {0x0000a100, 0x06010602},
-       {0x0000a104, 0x061f0600},
-       {0x0000a108, 0x061d061e},
-       {0x0000a10c, 0x07020703},
-       {0x0000a110, 0x07000701},
-       {0x0000a114, 0x00000000},
-       {0x0000a118, 0x00000000},
-       {0x0000a11c, 0x00000000},
-       {0x0000a120, 0x00000000},
-       {0x0000a124, 0x00000000},
-       {0x0000a128, 0x00000000},
-       {0x0000a12c, 0x00000000},
-       {0x0000a130, 0x00000000},
-       {0x0000a134, 0x00000000},
-       {0x0000a138, 0x00000000},
-       {0x0000a13c, 0x00000000},
-       {0x0000a140, 0x001f0000},
-       {0x0000a144, 0x01000101},
-       {0x0000a148, 0x011e011f},
-       {0x0000a14c, 0x011c011d},
-       {0x0000a150, 0x02030204},
-       {0x0000a154, 0x02010202},
-       {0x0000a158, 0x021f0200},
-       {0x0000a15c, 0x0302021e},
-       {0x0000a160, 0x03000301},
-       {0x0000a164, 0x031e031f},
-       {0x0000a168, 0x0402031d},
-       {0x0000a16c, 0x04000401},
-       {0x0000a170, 0x041e041f},
-       {0x0000a174, 0x0502041d},
-       {0x0000a178, 0x05000501},
-       {0x0000a17c, 0x051e051f},
-       {0x0000a180, 0x06010602},
-       {0x0000a184, 0x061f0600},
-       {0x0000a188, 0x061d061e},
-       {0x0000a18c, 0x07020703},
-       {0x0000a190, 0x07000701},
-       {0x0000a194, 0x00000000},
-       {0x0000a198, 0x00000000},
-       {0x0000a19c, 0x00000000},
-       {0x0000a1a0, 0x00000000},
-       {0x0000a1a4, 0x00000000},
-       {0x0000a1a8, 0x00000000},
-       {0x0000a1ac, 0x00000000},
-       {0x0000a1b0, 0x00000000},
-       {0x0000a1b4, 0x00000000},
-       {0x0000a1b8, 0x00000000},
-       {0x0000a1bc, 0x00000000},
-       {0x0000a1c0, 0x00000000},
-       {0x0000a1c4, 0x00000000},
-       {0x0000a1c8, 0x00000000},
-       {0x0000a1cc, 0x00000000},
-       {0x0000a1d0, 0x00000000},
-       {0x0000a1d4, 0x00000000},
-       {0x0000a1d8, 0x00000000},
-       {0x0000a1dc, 0x00000000},
-       {0x0000a1e0, 0x00000000},
-       {0x0000a1e4, 0x00000000},
-       {0x0000a1e8, 0x00000000},
-       {0x0000a1ec, 0x00000000},
-       {0x0000a1f0, 0x00000396},
-       {0x0000a1f4, 0x00000396},
-       {0x0000a1f8, 0x00000396},
-       {0x0000a1fc, 0x00000196},
-       {0x0000b000, 0x00010000},
-       {0x0000b004, 0x00030002},
-       {0x0000b008, 0x00050004},
-       {0x0000b00c, 0x00810080},
-       {0x0000b010, 0x00830082},
-       {0x0000b014, 0x01810180},
-       {0x0000b018, 0x01830182},
-       {0x0000b01c, 0x01850184},
-       {0x0000b020, 0x02810280},
-       {0x0000b024, 0x02830282},
-       {0x0000b028, 0x02850284},
-       {0x0000b02c, 0x02890288},
-       {0x0000b030, 0x028b028a},
-       {0x0000b034, 0x0388028c},
-       {0x0000b038, 0x038a0389},
-       {0x0000b03c, 0x038c038b},
-       {0x0000b040, 0x0390038d},
-       {0x0000b044, 0x03920391},
-       {0x0000b048, 0x03940393},
-       {0x0000b04c, 0x03960395},
-       {0x0000b050, 0x00000000},
-       {0x0000b054, 0x00000000},
-       {0x0000b058, 0x00000000},
-       {0x0000b05c, 0x00000000},
-       {0x0000b060, 0x00000000},
-       {0x0000b064, 0x00000000},
-       {0x0000b068, 0x00000000},
-       {0x0000b06c, 0x00000000},
-       {0x0000b070, 0x00000000},
-       {0x0000b074, 0x00000000},
-       {0x0000b078, 0x00000000},
-       {0x0000b07c, 0x00000000},
-       {0x0000b080, 0x2a2d2f32},
-       {0x0000b084, 0x21232328},
-       {0x0000b088, 0x19191c1e},
-       {0x0000b08c, 0x12141417},
-       {0x0000b090, 0x07070e0e},
-       {0x0000b094, 0x03030305},
-       {0x0000b098, 0x00000003},
-       {0x0000b09c, 0x00000000},
-       {0x0000b0a0, 0x00000000},
-       {0x0000b0a4, 0x00000000},
-       {0x0000b0a8, 0x00000000},
-       {0x0000b0ac, 0x00000000},
-       {0x0000b0b0, 0x00000000},
-       {0x0000b0b4, 0x00000000},
-       {0x0000b0b8, 0x00000000},
-       {0x0000b0bc, 0x00000000},
-       {0x0000b0c0, 0x003f0020},
-       {0x0000b0c4, 0x00400041},
-       {0x0000b0c8, 0x0140005f},
-       {0x0000b0cc, 0x0160015f},
-       {0x0000b0d0, 0x017e017f},
-       {0x0000b0d4, 0x02410242},
-       {0x0000b0d8, 0x025f0240},
-       {0x0000b0dc, 0x027f0260},
-       {0x0000b0e0, 0x0341027e},
-       {0x0000b0e4, 0x035f0340},
-       {0x0000b0e8, 0x037f0360},
-       {0x0000b0ec, 0x04400441},
-       {0x0000b0f0, 0x0460045f},
-       {0x0000b0f4, 0x0541047f},
-       {0x0000b0f8, 0x055f0540},
-       {0x0000b0fc, 0x057f0560},
-       {0x0000b100, 0x06400641},
-       {0x0000b104, 0x0660065f},
-       {0x0000b108, 0x067e067f},
-       {0x0000b10c, 0x07410742},
-       {0x0000b110, 0x075f0740},
-       {0x0000b114, 0x077f0760},
-       {0x0000b118, 0x07800781},
-       {0x0000b11c, 0x07a0079f},
-       {0x0000b120, 0x07c107bf},
-       {0x0000b124, 0x000007c0},
-       {0x0000b128, 0x00000000},
-       {0x0000b12c, 0x00000000},
-       {0x0000b130, 0x00000000},
-       {0x0000b134, 0x00000000},
-       {0x0000b138, 0x00000000},
-       {0x0000b13c, 0x00000000},
-       {0x0000b140, 0x003f0020},
-       {0x0000b144, 0x00400041},
-       {0x0000b148, 0x0140005f},
-       {0x0000b14c, 0x0160015f},
-       {0x0000b150, 0x017e017f},
-       {0x0000b154, 0x02410242},
-       {0x0000b158, 0x025f0240},
-       {0x0000b15c, 0x027f0260},
-       {0x0000b160, 0x0341027e},
-       {0x0000b164, 0x035f0340},
-       {0x0000b168, 0x037f0360},
-       {0x0000b16c, 0x04400441},
-       {0x0000b170, 0x0460045f},
-       {0x0000b174, 0x0541047f},
-       {0x0000b178, 0x055f0540},
-       {0x0000b17c, 0x057f0560},
-       {0x0000b180, 0x06400641},
-       {0x0000b184, 0x0660065f},
-       {0x0000b188, 0x067e067f},
-       {0x0000b18c, 0x07410742},
-       {0x0000b190, 0x075f0740},
-       {0x0000b194, 0x077f0760},
-       {0x0000b198, 0x07800781},
-       {0x0000b19c, 0x07a0079f},
-       {0x0000b1a0, 0x07c107bf},
-       {0x0000b1a4, 0x000007c0},
-       {0x0000b1a8, 0x00000000},
-       {0x0000b1ac, 0x00000000},
-       {0x0000b1b0, 0x00000000},
-       {0x0000b1b4, 0x00000000},
-       {0x0000b1b8, 0x00000000},
-       {0x0000b1bc, 0x00000000},
-       {0x0000b1c0, 0x00000000},
-       {0x0000b1c4, 0x00000000},
-       {0x0000b1c8, 0x00000000},
-       {0x0000b1cc, 0x00000000},
-       {0x0000b1d0, 0x00000000},
-       {0x0000b1d4, 0x00000000},
-       {0x0000b1d8, 0x00000000},
-       {0x0000b1dc, 0x00000000},
-       {0x0000b1e0, 0x00000000},
-       {0x0000b1e4, 0x00000000},
-       {0x0000b1e8, 0x00000000},
-       {0x0000b1ec, 0x00000000},
-       {0x0000b1f0, 0x00000396},
-       {0x0000b1f4, 0x00000396},
-       {0x0000b1f8, 0x00000396},
-       {0x0000b1fc, 0x00000196},
-};
-
-static const u32 ar9462_2p1_baseband_core_mix_rxgain[][2] = {
-       /* Addr      allmodes  */
-       {0x00009fd0, 0x0a2d6b93},
-};
-
-static const u32 ar9462_2p1_baseband_postamble_mix_rxgain[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae},
-       {0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da},
-       {0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81},
-       {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8},
-       {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e},
-       {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e},
-};
-
-static const u32 ar9462_2p1_baseband_postamble_5g_xlna[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
-};
-
-static const u32 ar9462_2p1_common_wo_xlna_rx_gain[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x00010000},
-       {0x0000a004, 0x00030002},
-       {0x0000a008, 0x00050004},
-       {0x0000a00c, 0x00810080},
-       {0x0000a010, 0x00830082},
-       {0x0000a014, 0x01810180},
-       {0x0000a018, 0x01830182},
-       {0x0000a01c, 0x01850184},
-       {0x0000a020, 0x01890188},
-       {0x0000a024, 0x018b018a},
-       {0x0000a028, 0x018d018c},
-       {0x0000a02c, 0x03820190},
-       {0x0000a030, 0x03840383},
-       {0x0000a034, 0x03880385},
-       {0x0000a038, 0x038a0389},
-       {0x0000a03c, 0x038c038b},
-       {0x0000a040, 0x0390038d},
-       {0x0000a044, 0x03920391},
-       {0x0000a048, 0x03940393},
-       {0x0000a04c, 0x03960395},
-       {0x0000a050, 0x00000000},
-       {0x0000a054, 0x00000000},
-       {0x0000a058, 0x00000000},
-       {0x0000a05c, 0x00000000},
-       {0x0000a060, 0x00000000},
-       {0x0000a064, 0x00000000},
-       {0x0000a068, 0x00000000},
-       {0x0000a06c, 0x00000000},
-       {0x0000a070, 0x00000000},
-       {0x0000a074, 0x00000000},
-       {0x0000a078, 0x00000000},
-       {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x29292929},
-       {0x0000a084, 0x29292929},
-       {0x0000a088, 0x29292929},
-       {0x0000a08c, 0x29292929},
-       {0x0000a090, 0x22292929},
-       {0x0000a094, 0x1d1d2222},
-       {0x0000a098, 0x0c111117},
-       {0x0000a09c, 0x00030303},
-       {0x0000a0a0, 0x00000000},
-       {0x0000a0a4, 0x00000000},
-       {0x0000a0a8, 0x00000000},
-       {0x0000a0ac, 0x00000000},
-       {0x0000a0b0, 0x00000000},
-       {0x0000a0b4, 0x00000000},
-       {0x0000a0b8, 0x00000000},
-       {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x01000101},
-       {0x0000a0c8, 0x011e011f},
-       {0x0000a0cc, 0x011c011d},
-       {0x0000a0d0, 0x02030204},
-       {0x0000a0d4, 0x02010202},
-       {0x0000a0d8, 0x021f0200},
-       {0x0000a0dc, 0x0302021e},
-       {0x0000a0e0, 0x03000301},
-       {0x0000a0e4, 0x031e031f},
-       {0x0000a0e8, 0x0402031d},
-       {0x0000a0ec, 0x04000401},
-       {0x0000a0f0, 0x041e041f},
-       {0x0000a0f4, 0x0502041d},
-       {0x0000a0f8, 0x05000501},
-       {0x0000a0fc, 0x051e051f},
-       {0x0000a100, 0x06010602},
-       {0x0000a104, 0x061f0600},
-       {0x0000a108, 0x061d061e},
-       {0x0000a10c, 0x07020703},
-       {0x0000a110, 0x07000701},
-       {0x0000a114, 0x00000000},
-       {0x0000a118, 0x00000000},
-       {0x0000a11c, 0x00000000},
-       {0x0000a120, 0x00000000},
-       {0x0000a124, 0x00000000},
-       {0x0000a128, 0x00000000},
-       {0x0000a12c, 0x00000000},
-       {0x0000a130, 0x00000000},
-       {0x0000a134, 0x00000000},
-       {0x0000a138, 0x00000000},
-       {0x0000a13c, 0x00000000},
-       {0x0000a140, 0x001f0000},
-       {0x0000a144, 0x01000101},
-       {0x0000a148, 0x011e011f},
-       {0x0000a14c, 0x011c011d},
-       {0x0000a150, 0x02030204},
-       {0x0000a154, 0x02010202},
-       {0x0000a158, 0x021f0200},
-       {0x0000a15c, 0x0302021e},
-       {0x0000a160, 0x03000301},
-       {0x0000a164, 0x031e031f},
-       {0x0000a168, 0x0402031d},
-       {0x0000a16c, 0x04000401},
-       {0x0000a170, 0x041e041f},
-       {0x0000a174, 0x0502041d},
-       {0x0000a178, 0x05000501},
-       {0x0000a17c, 0x051e051f},
-       {0x0000a180, 0x06010602},
-       {0x0000a184, 0x061f0600},
-       {0x0000a188, 0x061d061e},
-       {0x0000a18c, 0x07020703},
-       {0x0000a190, 0x07000701},
-       {0x0000a194, 0x00000000},
-       {0x0000a198, 0x00000000},
-       {0x0000a19c, 0x00000000},
-       {0x0000a1a0, 0x00000000},
-       {0x0000a1a4, 0x00000000},
-       {0x0000a1a8, 0x00000000},
-       {0x0000a1ac, 0x00000000},
-       {0x0000a1b0, 0x00000000},
-       {0x0000a1b4, 0x00000000},
-       {0x0000a1b8, 0x00000000},
-       {0x0000a1bc, 0x00000000},
-       {0x0000a1c0, 0x00000000},
-       {0x0000a1c4, 0x00000000},
-       {0x0000a1c8, 0x00000000},
-       {0x0000a1cc, 0x00000000},
-       {0x0000a1d0, 0x00000000},
-       {0x0000a1d4, 0x00000000},
-       {0x0000a1d8, 0x00000000},
-       {0x0000a1dc, 0x00000000},
-       {0x0000a1e0, 0x00000000},
-       {0x0000a1e4, 0x00000000},
-       {0x0000a1e8, 0x00000000},
-       {0x0000a1ec, 0x00000000},
-       {0x0000a1f0, 0x00000396},
-       {0x0000a1f4, 0x00000396},
-       {0x0000a1f8, 0x00000396},
-       {0x0000a1fc, 0x00000196},
-       {0x0000b000, 0x00010000},
-       {0x0000b004, 0x00030002},
-       {0x0000b008, 0x00050004},
-       {0x0000b00c, 0x00810080},
-       {0x0000b010, 0x00830082},
-       {0x0000b014, 0x01810180},
-       {0x0000b018, 0x01830182},
-       {0x0000b01c, 0x01850184},
-       {0x0000b020, 0x02810280},
-       {0x0000b024, 0x02830282},
-       {0x0000b028, 0x02850284},
-       {0x0000b02c, 0x02890288},
-       {0x0000b030, 0x028b028a},
-       {0x0000b034, 0x0388028c},
-       {0x0000b038, 0x038a0389},
-       {0x0000b03c, 0x038c038b},
-       {0x0000b040, 0x0390038d},
-       {0x0000b044, 0x03920391},
-       {0x0000b048, 0x03940393},
-       {0x0000b04c, 0x03960395},
-       {0x0000b050, 0x00000000},
-       {0x0000b054, 0x00000000},
-       {0x0000b058, 0x00000000},
-       {0x0000b05c, 0x00000000},
-       {0x0000b060, 0x00000000},
-       {0x0000b064, 0x00000000},
-       {0x0000b068, 0x00000000},
-       {0x0000b06c, 0x00000000},
-       {0x0000b070, 0x00000000},
-       {0x0000b074, 0x00000000},
-       {0x0000b078, 0x00000000},
-       {0x0000b07c, 0x00000000},
-       {0x0000b080, 0x32323232},
-       {0x0000b084, 0x2f2f3232},
-       {0x0000b088, 0x23282a2d},
-       {0x0000b08c, 0x1c1e2123},
-       {0x0000b090, 0x14171919},
-       {0x0000b094, 0x0e0e1214},
-       {0x0000b098, 0x03050707},
-       {0x0000b09c, 0x00030303},
-       {0x0000b0a0, 0x00000000},
-       {0x0000b0a4, 0x00000000},
-       {0x0000b0a8, 0x00000000},
-       {0x0000b0ac, 0x00000000},
-       {0x0000b0b0, 0x00000000},
-       {0x0000b0b4, 0x00000000},
-       {0x0000b0b8, 0x00000000},
-       {0x0000b0bc, 0x00000000},
-       {0x0000b0c0, 0x003f0020},
-       {0x0000b0c4, 0x00400041},
-       {0x0000b0c8, 0x0140005f},
-       {0x0000b0cc, 0x0160015f},
-       {0x0000b0d0, 0x017e017f},
-       {0x0000b0d4, 0x02410242},
-       {0x0000b0d8, 0x025f0240},
-       {0x0000b0dc, 0x027f0260},
-       {0x0000b0e0, 0x0341027e},
-       {0x0000b0e4, 0x035f0340},
-       {0x0000b0e8, 0x037f0360},
-       {0x0000b0ec, 0x04400441},
-       {0x0000b0f0, 0x0460045f},
-       {0x0000b0f4, 0x0541047f},
-       {0x0000b0f8, 0x055f0540},
-       {0x0000b0fc, 0x057f0560},
-       {0x0000b100, 0x06400641},
-       {0x0000b104, 0x0660065f},
-       {0x0000b108, 0x067e067f},
-       {0x0000b10c, 0x07410742},
-       {0x0000b110, 0x075f0740},
-       {0x0000b114, 0x077f0760},
-       {0x0000b118, 0x07800781},
-       {0x0000b11c, 0x07a0079f},
-       {0x0000b120, 0x07c107bf},
-       {0x0000b124, 0x000007c0},
-       {0x0000b128, 0x00000000},
-       {0x0000b12c, 0x00000000},
-       {0x0000b130, 0x00000000},
-       {0x0000b134, 0x00000000},
-       {0x0000b138, 0x00000000},
-       {0x0000b13c, 0x00000000},
-       {0x0000b140, 0x003f0020},
-       {0x0000b144, 0x00400041},
-       {0x0000b148, 0x0140005f},
-       {0x0000b14c, 0x0160015f},
-       {0x0000b150, 0x017e017f},
-       {0x0000b154, 0x02410242},
-       {0x0000b158, 0x025f0240},
-       {0x0000b15c, 0x027f0260},
-       {0x0000b160, 0x0341027e},
-       {0x0000b164, 0x035f0340},
-       {0x0000b168, 0x037f0360},
-       {0x0000b16c, 0x04400441},
-       {0x0000b170, 0x0460045f},
-       {0x0000b174, 0x0541047f},
-       {0x0000b178, 0x055f0540},
-       {0x0000b17c, 0x057f0560},
-       {0x0000b180, 0x06400641},
-       {0x0000b184, 0x0660065f},
-       {0x0000b188, 0x067e067f},
-       {0x0000b18c, 0x07410742},
-       {0x0000b190, 0x075f0740},
-       {0x0000b194, 0x077f0760},
-       {0x0000b198, 0x07800781},
-       {0x0000b19c, 0x07a0079f},
-       {0x0000b1a0, 0x07c107bf},
-       {0x0000b1a4, 0x000007c0},
-       {0x0000b1a8, 0x00000000},
-       {0x0000b1ac, 0x00000000},
-       {0x0000b1b0, 0x00000000},
-       {0x0000b1b4, 0x00000000},
-       {0x0000b1b8, 0x00000000},
-       {0x0000b1bc, 0x00000000},
-       {0x0000b1c0, 0x00000000},
-       {0x0000b1c4, 0x00000000},
-       {0x0000b1c8, 0x00000000},
-       {0x0000b1cc, 0x00000000},
-       {0x0000b1d0, 0x00000000},
-       {0x0000b1d4, 0x00000000},
-       {0x0000b1d8, 0x00000000},
-       {0x0000b1dc, 0x00000000},
-       {0x0000b1e0, 0x00000000},
-       {0x0000b1e4, 0x00000000},
-       {0x0000b1e8, 0x00000000},
-       {0x0000b1ec, 0x00000000},
-       {0x0000b1f0, 0x00000396},
-       {0x0000b1f4, 0x00000396},
-       {0x0000b1f8, 0x00000396},
-       {0x0000b1fc, 0x00000196},
-};
-
-static const u32 ar9462_2p1_common_5g_xlna_only_rx_gain[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x00010000},
-       {0x0000a004, 0x00030002},
-       {0x0000a008, 0x00050004},
-       {0x0000a00c, 0x00810080},
-       {0x0000a010, 0x00830082},
-       {0x0000a014, 0x01810180},
-       {0x0000a018, 0x01830182},
-       {0x0000a01c, 0x01850184},
-       {0x0000a020, 0x01890188},
-       {0x0000a024, 0x018b018a},
-       {0x0000a028, 0x018d018c},
-       {0x0000a02c, 0x03820190},
-       {0x0000a030, 0x03840383},
-       {0x0000a034, 0x03880385},
-       {0x0000a038, 0x038a0389},
-       {0x0000a03c, 0x038c038b},
-       {0x0000a040, 0x0390038d},
-       {0x0000a044, 0x03920391},
-       {0x0000a048, 0x03940393},
-       {0x0000a04c, 0x03960395},
-       {0x0000a050, 0x00000000},
-       {0x0000a054, 0x00000000},
-       {0x0000a058, 0x00000000},
-       {0x0000a05c, 0x00000000},
-       {0x0000a060, 0x00000000},
-       {0x0000a064, 0x00000000},
-       {0x0000a068, 0x00000000},
-       {0x0000a06c, 0x00000000},
-       {0x0000a070, 0x00000000},
-       {0x0000a074, 0x00000000},
-       {0x0000a078, 0x00000000},
-       {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x29292929},
-       {0x0000a084, 0x29292929},
-       {0x0000a088, 0x29292929},
-       {0x0000a08c, 0x29292929},
-       {0x0000a090, 0x22292929},
-       {0x0000a094, 0x1d1d2222},
-       {0x0000a098, 0x0c111117},
-       {0x0000a09c, 0x00030303},
-       {0x0000a0a0, 0x00000000},
-       {0x0000a0a4, 0x00000000},
-       {0x0000a0a8, 0x00000000},
-       {0x0000a0ac, 0x00000000},
-       {0x0000a0b0, 0x00000000},
-       {0x0000a0b4, 0x00000000},
-       {0x0000a0b8, 0x00000000},
-       {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x01000101},
-       {0x0000a0c8, 0x011e011f},
-       {0x0000a0cc, 0x011c011d},
-       {0x0000a0d0, 0x02030204},
-       {0x0000a0d4, 0x02010202},
-       {0x0000a0d8, 0x021f0200},
-       {0x0000a0dc, 0x0302021e},
-       {0x0000a0e0, 0x03000301},
-       {0x0000a0e4, 0x031e031f},
-       {0x0000a0e8, 0x0402031d},
-       {0x0000a0ec, 0x04000401},
-       {0x0000a0f0, 0x041e041f},
-       {0x0000a0f4, 0x0502041d},
-       {0x0000a0f8, 0x05000501},
-       {0x0000a0fc, 0x051e051f},
-       {0x0000a100, 0x06010602},
-       {0x0000a104, 0x061f0600},
-       {0x0000a108, 0x061d061e},
-       {0x0000a10c, 0x07020703},
-       {0x0000a110, 0x07000701},
-       {0x0000a114, 0x00000000},
-       {0x0000a118, 0x00000000},
-       {0x0000a11c, 0x00000000},
-       {0x0000a120, 0x00000000},
-       {0x0000a124, 0x00000000},
-       {0x0000a128, 0x00000000},
-       {0x0000a12c, 0x00000000},
-       {0x0000a130, 0x00000000},
-       {0x0000a134, 0x00000000},
-       {0x0000a138, 0x00000000},
-       {0x0000a13c, 0x00000000},
-       {0x0000a140, 0x001f0000},
-       {0x0000a144, 0x01000101},
-       {0x0000a148, 0x011e011f},
-       {0x0000a14c, 0x011c011d},
-       {0x0000a150, 0x02030204},
-       {0x0000a154, 0x02010202},
-       {0x0000a158, 0x021f0200},
-       {0x0000a15c, 0x0302021e},
-       {0x0000a160, 0x03000301},
-       {0x0000a164, 0x031e031f},
-       {0x0000a168, 0x0402031d},
-       {0x0000a16c, 0x04000401},
-       {0x0000a170, 0x041e041f},
-       {0x0000a174, 0x0502041d},
-       {0x0000a178, 0x05000501},
-       {0x0000a17c, 0x051e051f},
-       {0x0000a180, 0x06010602},
-       {0x0000a184, 0x061f0600},
-       {0x0000a188, 0x061d061e},
-       {0x0000a18c, 0x07020703},
-       {0x0000a190, 0x07000701},
-       {0x0000a194, 0x00000000},
-       {0x0000a198, 0x00000000},
-       {0x0000a19c, 0x00000000},
-       {0x0000a1a0, 0x00000000},
-       {0x0000a1a4, 0x00000000},
-       {0x0000a1a8, 0x00000000},
-       {0x0000a1ac, 0x00000000},
-       {0x0000a1b0, 0x00000000},
-       {0x0000a1b4, 0x00000000},
-       {0x0000a1b8, 0x00000000},
-       {0x0000a1bc, 0x00000000},
-       {0x0000a1c0, 0x00000000},
-       {0x0000a1c4, 0x00000000},
-       {0x0000a1c8, 0x00000000},
-       {0x0000a1cc, 0x00000000},
-       {0x0000a1d0, 0x00000000},
-       {0x0000a1d4, 0x00000000},
-       {0x0000a1d8, 0x00000000},
-       {0x0000a1dc, 0x00000000},
-       {0x0000a1e0, 0x00000000},
-       {0x0000a1e4, 0x00000000},
-       {0x0000a1e8, 0x00000000},
-       {0x0000a1ec, 0x00000000},
-       {0x0000a1f0, 0x00000396},
-       {0x0000a1f4, 0x00000396},
-       {0x0000a1f8, 0x00000396},
-       {0x0000a1fc, 0x00000196},
-       {0x0000b000, 0x00010000},
-       {0x0000b004, 0x00030002},
-       {0x0000b008, 0x00050004},
-       {0x0000b00c, 0x00810080},
-       {0x0000b010, 0x00830082},
-       {0x0000b014, 0x01810180},
-       {0x0000b018, 0x01830182},
-       {0x0000b01c, 0x01850184},
-       {0x0000b020, 0x02810280},
-       {0x0000b024, 0x02830282},
-       {0x0000b028, 0x02850284},
-       {0x0000b02c, 0x02890288},
-       {0x0000b030, 0x028b028a},
-       {0x0000b034, 0x0388028c},
-       {0x0000b038, 0x038a0389},
-       {0x0000b03c, 0x038c038b},
-       {0x0000b040, 0x0390038d},
-       {0x0000b044, 0x03920391},
-       {0x0000b048, 0x03940393},
-       {0x0000b04c, 0x03960395},
-       {0x0000b050, 0x00000000},
-       {0x0000b054, 0x00000000},
-       {0x0000b058, 0x00000000},
-       {0x0000b05c, 0x00000000},
-       {0x0000b060, 0x00000000},
-       {0x0000b064, 0x00000000},
-       {0x0000b068, 0x00000000},
-       {0x0000b06c, 0x00000000},
-       {0x0000b070, 0x00000000},
-       {0x0000b074, 0x00000000},
-       {0x0000b078, 0x00000000},
-       {0x0000b07c, 0x00000000},
-       {0x0000b080, 0x2a2d2f32},
-       {0x0000b084, 0x21232328},
-       {0x0000b088, 0x19191c1e},
-       {0x0000b08c, 0x12141417},
-       {0x0000b090, 0x07070e0e},
-       {0x0000b094, 0x03030305},
-       {0x0000b098, 0x00000003},
-       {0x0000b09c, 0x00000000},
-       {0x0000b0a0, 0x00000000},
-       {0x0000b0a4, 0x00000000},
-       {0x0000b0a8, 0x00000000},
-       {0x0000b0ac, 0x00000000},
-       {0x0000b0b0, 0x00000000},
-       {0x0000b0b4, 0x00000000},
-       {0x0000b0b8, 0x00000000},
-       {0x0000b0bc, 0x00000000},
-       {0x0000b0c0, 0x003f0020},
-       {0x0000b0c4, 0x00400041},
-       {0x0000b0c8, 0x0140005f},
-       {0x0000b0cc, 0x0160015f},
-       {0x0000b0d0, 0x017e017f},
-       {0x0000b0d4, 0x02410242},
-       {0x0000b0d8, 0x025f0240},
-       {0x0000b0dc, 0x027f0260},
-       {0x0000b0e0, 0x0341027e},
-       {0x0000b0e4, 0x035f0340},
-       {0x0000b0e8, 0x037f0360},
-       {0x0000b0ec, 0x04400441},
-       {0x0000b0f0, 0x0460045f},
-       {0x0000b0f4, 0x0541047f},
-       {0x0000b0f8, 0x055f0540},
-       {0x0000b0fc, 0x057f0560},
-       {0x0000b100, 0x06400641},
-       {0x0000b104, 0x0660065f},
-       {0x0000b108, 0x067e067f},
-       {0x0000b10c, 0x07410742},
-       {0x0000b110, 0x075f0740},
-       {0x0000b114, 0x077f0760},
-       {0x0000b118, 0x07800781},
-       {0x0000b11c, 0x07a0079f},
-       {0x0000b120, 0x07c107bf},
-       {0x0000b124, 0x000007c0},
-       {0x0000b128, 0x00000000},
-       {0x0000b12c, 0x00000000},
-       {0x0000b130, 0x00000000},
-       {0x0000b134, 0x00000000},
-       {0x0000b138, 0x00000000},
-       {0x0000b13c, 0x00000000},
-       {0x0000b140, 0x003f0020},
-       {0x0000b144, 0x00400041},
-       {0x0000b148, 0x0140005f},
-       {0x0000b14c, 0x0160015f},
-       {0x0000b150, 0x017e017f},
-       {0x0000b154, 0x02410242},
-       {0x0000b158, 0x025f0240},
-       {0x0000b15c, 0x027f0260},
-       {0x0000b160, 0x0341027e},
-       {0x0000b164, 0x035f0340},
-       {0x0000b168, 0x037f0360},
-       {0x0000b16c, 0x04400441},
-       {0x0000b170, 0x0460045f},
-       {0x0000b174, 0x0541047f},
-       {0x0000b178, 0x055f0540},
-       {0x0000b17c, 0x057f0560},
-       {0x0000b180, 0x06400641},
-       {0x0000b184, 0x0660065f},
-       {0x0000b188, 0x067e067f},
-       {0x0000b18c, 0x07410742},
-       {0x0000b190, 0x075f0740},
-       {0x0000b194, 0x077f0760},
-       {0x0000b198, 0x07800781},
-       {0x0000b19c, 0x07a0079f},
-       {0x0000b1a0, 0x07c107bf},
-       {0x0000b1a4, 0x000007c0},
-       {0x0000b1a8, 0x00000000},
-       {0x0000b1ac, 0x00000000},
-       {0x0000b1b0, 0x00000000},
-       {0x0000b1b4, 0x00000000},
-       {0x0000b1b8, 0x00000000},
-       {0x0000b1bc, 0x00000000},
-       {0x0000b1c0, 0x00000000},
-       {0x0000b1c4, 0x00000000},
-       {0x0000b1c8, 0x00000000},
-       {0x0000b1cc, 0x00000000},
-       {0x0000b1d0, 0x00000000},
-       {0x0000b1d4, 0x00000000},
-       {0x0000b1d8, 0x00000000},
-       {0x0000b1dc, 0x00000000},
-       {0x0000b1e0, 0x00000000},
-       {0x0000b1e4, 0x00000000},
-       {0x0000b1e8, 0x00000000},
-       {0x0000b1ec, 0x00000000},
-       {0x0000b1f0, 0x00000396},
-       {0x0000b1f4, 0x00000396},
-       {0x0000b1f8, 0x00000396},
-       {0x0000b1fc, 0x00000196},
-};
-
-static const u32 ar9462_2p1_modes_low_ob_db_tx_gain[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
-       {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
-       {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
-       {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
-       {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
-       {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
-       {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
-       {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
-       {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
-       {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
-       {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
-       {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
-       {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
-       {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
-       {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
-       {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
-       {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
-       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
-       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
-       {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
-       {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
-       {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
-       {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
-       {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
-       {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
-       {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
-       {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
-       {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
-       {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
-       {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
-       {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
-       {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
-       {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
-       {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
-       {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-       {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-       {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-       {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-       {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
-       {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
-       {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
-       {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060},
-       {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
-       {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
-       {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000},
-       {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
-};
-
-static const u32 ar9462_2p1_modes_high_ob_db_tx_gain[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
-       {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
-       {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
-       {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de},
-       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
-       {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
-       {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
-       {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
-       {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
-       {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400},
-       {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402},
-       {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
-       {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603},
-       {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02},
-       {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04},
-       {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20},
-       {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20},
-       {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22},
-       {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24},
-       {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
-       {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
-       {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
-       {0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81},
-       {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83},
-       {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84},
-       {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
-       {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
-       {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
-       {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
-       {0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec},
-       {0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0},
-       {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4},
-       {0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
-       {0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
-       {0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
-       {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
-       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
-       {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
-       {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
-       {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
-       {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
-       {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
-       {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
-       {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
-       {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
-       {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
-       {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060},
-       {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
-       {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
-       {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000},
-       {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
-};
-
-static const u32 ar9462_2p1_modes_mix_ob_db_tx_gain[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
-       {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
-       {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
-       {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de},
-       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
-       {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
-       {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
-       {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
-       {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
-       {0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400},
-       {0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402},
-       {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
-       {0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603},
-       {0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02},
-       {0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04},
-       {0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20},
-       {0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20},
-       {0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22},
-       {0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24},
-       {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640},
-       {0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660},
-       {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861},
-       {0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81},
-       {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83},
-       {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84},
-       {0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3},
-       {0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5},
-       {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9},
-       {0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb},
-       {0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec},
-       {0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0},
-       {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4},
-       {0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
-       {0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
-       {0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
-       {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
-       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
-       {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
-       {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
-       {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
-       {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
-       {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
-       {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
-       {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
-       {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
-       {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-};
-
-static const u32 ar9462_2p1_modes_fast_clock[][3] = {
-       /* Addr      5G_HT20     5G_HT40   */
-       {0x00001030, 0x00000268, 0x000004d0},
-       {0x00001070, 0x0000018c, 0x00000318},
-       {0x000010b0, 0x00000fd0, 0x00001fa0},
-       {0x00008014, 0x044c044c, 0x08980898},
-       {0x0000801c, 0x148ec02b, 0x148ec057},
-       {0x00008318, 0x000044c0, 0x00008980},
-       {0x00009e00, 0x0372131c, 0x0372131c},
-       {0x0000a230, 0x0000400b, 0x00004016},
-       {0x0000a254, 0x00000898, 0x00001130},
-};
-
-static const u32 ar9462_2p1_baseband_core_txfir_coeff_japan_2484[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a398, 0x00000000},
-       {0x0000a39c, 0x6f7f0301},
-       {0x0000a3a0, 0xca9228ee},
-};
-
 #endif /* INITVALS_9462_2P1_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h
new file mode 100644 (file)
index 0000000..5681053
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-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.
+ */
+
+#ifndef INITVALS_9565_1P1_H
+#define INITVALS_9565_1P1_H
+
+/* AR9565 1.1 */
+
+#define ar9565_1p1_mac_core ar9565_1p0_mac_core
+
+#define ar9565_1p1_mac_postamble ar9565_1p0_mac_postamble
+
+#define ar9565_1p1_baseband_core ar9565_1p0_baseband_core
+
+#define ar9565_1p1_baseband_postamble ar9565_1p0_baseband_postamble
+
+#define ar9565_1p1_radio_core ar9565_1p0_radio_core
+
+#define ar9565_1p1_soc_preamble ar9565_1p0_soc_preamble
+
+#define ar9565_1p1_soc_postamble ar9565_1p0_soc_postamble
+
+#define ar9565_1p1_Common_rx_gain_table ar9565_1p0_Common_rx_gain_table
+
+#define ar9565_1p1_Modes_lowest_ob_db_tx_gain_table ar9565_1p0_Modes_lowest_ob_db_tx_gain_table
+
+#define ar9565_1p1_pciephy_clkreq_disable_L1 ar9565_1p0_pciephy_clkreq_disable_L1
+
+#define ar9565_1p1_modes_fast_clock ar9565_1p0_modes_fast_clock
+
+#define ar9565_1p1_common_wo_xlna_rx_gain_table ar9565_1p0_common_wo_xlna_rx_gain_table
+
+#define ar9565_1p1_modes_low_ob_db_tx_gain_table ar9565_1p0_modes_low_ob_db_tx_gain_table
+
+#define ar9565_1p1_modes_high_ob_db_tx_gain_table ar9565_1p0_modes_high_ob_db_tx_gain_table
+
+#define ar9565_1p1_modes_high_power_tx_gain_table ar9565_1p0_modes_high_power_tx_gain_table
+
+#define ar9565_1p1_baseband_core_txfir_coeff_japan_2484 ar9565_1p0_baseband_core_txfir_coeff_japan_2484
+
+static const u32 ar9565_1p1_radio_postamble[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
+       {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
+       {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
+       {0x0001610c, 0x40000000, 0x40000000, 0x40000000, 0x40000000},
+       {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
+};
+
+#endif /* INITVALS_9565_1P1_H */
index bdee2ed67219b6e1c56a0f03a6a28391ba3283aa..75bef1179d0d674f857b61f455f1ba045a44e35a 100644 (file)
 
 /* AR9580 1.0 */
 
+#define ar9580_1p0_soc_preamble ar9300_2p2_soc_preamble
+
+#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble
+
+#define ar9580_1p0_radio_core ar9300_2p2_radio_core
+
+#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble
+
+#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
+
+#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2
+
+#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
+
 #define ar9580_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2
 
+#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
+
 static const u32 ar9580_1p0_radio_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
        {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
        {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
-       {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0001610c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
        {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-       {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0001650c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
        {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-       {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0001690c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
        {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
 };
 
@@ -44,9 +60,9 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
        {0x00009814, 0x3280c00a},
        {0x00009818, 0x00000000},
        {0x0000981c, 0x00020028},
-       {0x00009834, 0x6400a290},
+       {0x00009834, 0x6400a190},
        {0x00009838, 0x0108ecff},
-       {0x0000983c, 0x0d000600},
+       {0x0000983c, 0x14000600},
        {0x00009880, 0x201fff00},
        {0x00009884, 0x00001042},
        {0x000098a4, 0x00200400},
@@ -67,7 +83,7 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
        {0x00009d04, 0x40206c10},
        {0x00009d08, 0x009c4060},
        {0x00009d0c, 0x9883800a},
-       {0x00009d10, 0x01834061},
+       {0x00009d10, 0x01884061},
        {0x00009d14, 0x00c0040b},
        {0x00009d18, 0x00000000},
        {0x00009e08, 0x0038230c},
@@ -198,8 +214,6 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
        {0x0000c420, 0x00000000},
 };
 
-#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble
-
 static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
@@ -306,7 +320,112 @@ static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = {
        {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 };
 
-#define ar9580_1p0_high_power_tx_gain_table ar9580_1p0_low_ob_db_tx_gain_table
+static const u32 ar9580_1p0_high_power_tx_gain_table[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
+       {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
+       {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
+       {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
+       {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
+       {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
+       {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
+       {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
+       {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
+       {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
+       {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
+       {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
+       {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
+       {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
+       {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
+       {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
+       {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83},
+       {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84},
+       {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
+       {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
+       {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
+       {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+       {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+       {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400},
+       {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402},
+       {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603},
+       {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02},
+       {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04},
+       {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20},
+       {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20},
+       {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22},
+       {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24},
+       {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640},
+       {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660},
+       {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861},
+       {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81},
+       {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83},
+       {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84},
+       {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3},
+       {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5},
+       {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9},
+       {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb},
+       {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
+       {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
+       {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
+       {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
+       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
+       {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
+       {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
+       {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
+       {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
+       {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
+       {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
+       {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
+       {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
+       {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
+       {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
+       {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
+       {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
+       {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+       {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016048, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
+       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016288, 0x05a2040a, 0x05a2040a, 0x05a20408, 0x05a20408},
+       {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016448, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
+       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016848, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
+       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
 
 static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
@@ -414,8 +533,6 @@ static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = {
        {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 };
 
-#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
-
 static const u32 ar9580_1p0_mac_core[][2] = {
        /* Addr      allmodes  */
        {0x00000008, 0x00000000},
@@ -679,14 +796,6 @@ static const u32 ar9580_1p0_mixed_ob_db_tx_gain_table[][5] = {
        {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 };
 
-#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
-
-#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble
-
-#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
-
-#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2
-
 static const u32 ar9580_1p0_type6_tx_gain_table[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
@@ -761,160 +870,264 @@ static const u32 ar9580_1p0_type6_tx_gain_table[][5] = {
        {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 };
 
-static const u32 ar9580_1p0_soc_preamble[][2] = {
-       /* Addr      allmodes  */
-       {0x000040a4, 0x00a0c1c9},
-       {0x00007008, 0x00000000},
-       {0x00007020, 0x00000000},
-       {0x00007034, 0x00000002},
-       {0x00007038, 0x000004c2},
-       {0x00007048, 0x00000008},
-};
-
-#define ar9580_1p0_rx_gain_table ar9462_common_rx_gain_table_2p0
-
-static const u32 ar9580_1p0_radio_core[][2] = {
+static const u32 ar9580_1p0_rx_gain_table[][2] = {
        /* Addr      allmodes  */
-       {0x00016000, 0x36db6db6},
-       {0x00016004, 0x6db6db40},
-       {0x00016008, 0x73f00000},
-       {0x0001600c, 0x00000000},
-       {0x00016040, 0x7f80fff8},
-       {0x0001604c, 0x76d005b5},
-       {0x00016050, 0x556cf031},
-       {0x00016054, 0x13449440},
-       {0x00016058, 0x0c51c92c},
-       {0x0001605c, 0x3db7fffc},
-       {0x00016060, 0xfffffffc},
-       {0x00016064, 0x000f0278},
-       {0x0001606c, 0x6db60000},
-       {0x00016080, 0x00000000},
-       {0x00016084, 0x0e48048c},
-       {0x00016088, 0x54214514},
-       {0x0001608c, 0x119f481e},
-       {0x00016090, 0x24926490},
-       {0x00016098, 0xd2888888},
-       {0x000160a0, 0x0a108ffe},
-       {0x000160a4, 0x812fc370},
-       {0x000160a8, 0x423c8000},
-       {0x000160b4, 0x92480080},
-       {0x000160c0, 0x00adb6d0},
-       {0x000160c4, 0x6db6db60},
-       {0x000160c8, 0x6db6db6c},
-       {0x000160cc, 0x01e6c000},
-       {0x00016100, 0x3fffbe01},
-       {0x00016104, 0xfff80000},
-       {0x00016108, 0x00080010},
-       {0x00016144, 0x02084080},
-       {0x00016148, 0x00000000},
-       {0x00016280, 0x058a0001},
-       {0x00016284, 0x3d840208},
-       {0x00016288, 0x05a20408},
-       {0x0001628c, 0x00038c07},
-       {0x00016290, 0x00000004},
-       {0x00016294, 0x458aa14f},
-       {0x00016380, 0x00000000},
-       {0x00016384, 0x00000000},
-       {0x00016388, 0x00800700},
-       {0x0001638c, 0x00800700},
-       {0x00016390, 0x00800700},
-       {0x00016394, 0x00000000},
-       {0x00016398, 0x00000000},
-       {0x0001639c, 0x00000000},
-       {0x000163a0, 0x00000001},
-       {0x000163a4, 0x00000001},
-       {0x000163a8, 0x00000000},
-       {0x000163ac, 0x00000000},
-       {0x000163b0, 0x00000000},
-       {0x000163b4, 0x00000000},
-       {0x000163b8, 0x00000000},
-       {0x000163bc, 0x00000000},
-       {0x000163c0, 0x000000a0},
-       {0x000163c4, 0x000c0000},
-       {0x000163c8, 0x14021402},
-       {0x000163cc, 0x00001402},
-       {0x000163d0, 0x00000000},
-       {0x000163d4, 0x00000000},
-       {0x00016400, 0x36db6db6},
-       {0x00016404, 0x6db6db40},
-       {0x00016408, 0x73f00000},
-       {0x0001640c, 0x00000000},
-       {0x00016440, 0x7f80fff8},
-       {0x0001644c, 0x76d005b5},
-       {0x00016450, 0x556cf031},
-       {0x00016454, 0x13449440},
-       {0x00016458, 0x0c51c92c},
-       {0x0001645c, 0x3db7fffc},
-       {0x00016460, 0xfffffffc},
-       {0x00016464, 0x000f0278},
-       {0x0001646c, 0x6db60000},
-       {0x00016500, 0x3fffbe01},
-       {0x00016504, 0xfff80000},
-       {0x00016508, 0x00080010},
-       {0x00016544, 0x02084080},
-       {0x00016548, 0x00000000},
-       {0x00016780, 0x00000000},
-       {0x00016784, 0x00000000},
-       {0x00016788, 0x00800700},
-       {0x0001678c, 0x00800700},
-       {0x00016790, 0x00800700},
-       {0x00016794, 0x00000000},
-       {0x00016798, 0x00000000},
-       {0x0001679c, 0x00000000},
-       {0x000167a0, 0x00000001},
-       {0x000167a4, 0x00000001},
-       {0x000167a8, 0x00000000},
-       {0x000167ac, 0x00000000},
-       {0x000167b0, 0x00000000},
-       {0x000167b4, 0x00000000},
-       {0x000167b8, 0x00000000},
-       {0x000167bc, 0x00000000},
-       {0x000167c0, 0x000000a0},
-       {0x000167c4, 0x000c0000},
-       {0x000167c8, 0x14021402},
-       {0x000167cc, 0x00001402},
-       {0x000167d0, 0x00000000},
-       {0x000167d4, 0x00000000},
-       {0x00016800, 0x36db6db6},
-       {0x00016804, 0x6db6db40},
-       {0x00016808, 0x73f00000},
-       {0x0001680c, 0x00000000},
-       {0x00016840, 0x7f80fff8},
-       {0x0001684c, 0x76d005b5},
-       {0x00016850, 0x556cf031},
-       {0x00016854, 0x13449440},
-       {0x00016858, 0x0c51c92c},
-       {0x0001685c, 0x3db7fffc},
-       {0x00016860, 0xfffffffc},
-       {0x00016864, 0x000f0278},
-       {0x0001686c, 0x6db60000},
-       {0x00016900, 0x3fffbe01},
-       {0x00016904, 0xfff80000},
-       {0x00016908, 0x00080010},
-       {0x00016944, 0x02084080},
-       {0x00016948, 0x00000000},
-       {0x00016b80, 0x00000000},
-       {0x00016b84, 0x00000000},
-       {0x00016b88, 0x00800700},
-       {0x00016b8c, 0x00800700},
-       {0x00016b90, 0x00800700},
-       {0x00016b94, 0x00000000},
-       {0x00016b98, 0x00000000},
-       {0x00016b9c, 0x00000000},
-       {0x00016ba0, 0x00000001},
-       {0x00016ba4, 0x00000001},
-       {0x00016ba8, 0x00000000},
-       {0x00016bac, 0x00000000},
-       {0x00016bb0, 0x00000000},
-       {0x00016bb4, 0x00000000},
-       {0x00016bb8, 0x00000000},
-       {0x00016bbc, 0x00000000},
-       {0x00016bc0, 0x000000a0},
-       {0x00016bc4, 0x000c0000},
-       {0x00016bc8, 0x14021402},
-       {0x00016bcc, 0x00001402},
-       {0x00016bd0, 0x00000000},
-       {0x00016bd4, 0x00000000},
+       {0x0000a000, 0x00010000},
+       {0x0000a004, 0x00030002},
+       {0x0000a008, 0x00050004},
+       {0x0000a00c, 0x00810080},
+       {0x0000a010, 0x00830082},
+       {0x0000a014, 0x01810180},
+       {0x0000a018, 0x01830182},
+       {0x0000a01c, 0x01850184},
+       {0x0000a020, 0x01890188},
+       {0x0000a024, 0x018b018a},
+       {0x0000a028, 0x018d018c},
+       {0x0000a02c, 0x01910190},
+       {0x0000a030, 0x01930192},
+       {0x0000a034, 0x01950194},
+       {0x0000a038, 0x038a0196},
+       {0x0000a03c, 0x038c038b},
+       {0x0000a040, 0x0390038d},
+       {0x0000a044, 0x03920391},
+       {0x0000a048, 0x03940393},
+       {0x0000a04c, 0x03960395},
+       {0x0000a050, 0x00000000},
+       {0x0000a054, 0x00000000},
+       {0x0000a058, 0x00000000},
+       {0x0000a05c, 0x00000000},
+       {0x0000a060, 0x00000000},
+       {0x0000a064, 0x00000000},
+       {0x0000a068, 0x00000000},
+       {0x0000a06c, 0x00000000},
+       {0x0000a070, 0x00000000},
+       {0x0000a074, 0x00000000},
+       {0x0000a078, 0x00000000},
+       {0x0000a07c, 0x00000000},
+       {0x0000a080, 0x22222229},
+       {0x0000a084, 0x1d1d1d1d},
+       {0x0000a088, 0x1d1d1d1d},
+       {0x0000a08c, 0x1d1d1d1d},
+       {0x0000a090, 0x171d1d1d},
+       {0x0000a094, 0x11111717},
+       {0x0000a098, 0x00030311},
+       {0x0000a09c, 0x00000000},
+       {0x0000a0a0, 0x00000000},
+       {0x0000a0a4, 0x00000000},
+       {0x0000a0a8, 0x00000000},
+       {0x0000a0ac, 0x00000000},
+       {0x0000a0b0, 0x00000000},
+       {0x0000a0b4, 0x00000000},
+       {0x0000a0b8, 0x00000000},
+       {0x0000a0bc, 0x00000000},
+       {0x0000a0c0, 0x001f0000},
+       {0x0000a0c4, 0x01000101},
+       {0x0000a0c8, 0x011e011f},
+       {0x0000a0cc, 0x011c011d},
+       {0x0000a0d0, 0x02030204},
+       {0x0000a0d4, 0x02010202},
+       {0x0000a0d8, 0x021f0200},
+       {0x0000a0dc, 0x0302021e},
+       {0x0000a0e0, 0x03000301},
+       {0x0000a0e4, 0x031e031f},
+       {0x0000a0e8, 0x0402031d},
+       {0x0000a0ec, 0x04000401},
+       {0x0000a0f0, 0x041e041f},
+       {0x0000a0f4, 0x0502041d},
+       {0x0000a0f8, 0x05000501},
+       {0x0000a0fc, 0x051e051f},
+       {0x0000a100, 0x06010602},
+       {0x0000a104, 0x061f0600},
+       {0x0000a108, 0x061d061e},
+       {0x0000a10c, 0x07020703},
+       {0x0000a110, 0x07000701},
+       {0x0000a114, 0x00000000},
+       {0x0000a118, 0x00000000},
+       {0x0000a11c, 0x00000000},
+       {0x0000a120, 0x00000000},
+       {0x0000a124, 0x00000000},
+       {0x0000a128, 0x00000000},
+       {0x0000a12c, 0x00000000},
+       {0x0000a130, 0x00000000},
+       {0x0000a134, 0x00000000},
+       {0x0000a138, 0x00000000},
+       {0x0000a13c, 0x00000000},
+       {0x0000a140, 0x001f0000},
+       {0x0000a144, 0x01000101},
+       {0x0000a148, 0x011e011f},
+       {0x0000a14c, 0x011c011d},
+       {0x0000a150, 0x02030204},
+       {0x0000a154, 0x02010202},
+       {0x0000a158, 0x021f0200},
+       {0x0000a15c, 0x0302021e},
+       {0x0000a160, 0x03000301},
+       {0x0000a164, 0x031e031f},
+       {0x0000a168, 0x0402031d},
+       {0x0000a16c, 0x04000401},
+       {0x0000a170, 0x041e041f},
+       {0x0000a174, 0x0502041d},
+       {0x0000a178, 0x05000501},
+       {0x0000a17c, 0x051e051f},
+       {0x0000a180, 0x06010602},
+       {0x0000a184, 0x061f0600},
+       {0x0000a188, 0x061d061e},
+       {0x0000a18c, 0x07020703},
+       {0x0000a190, 0x07000701},
+       {0x0000a194, 0x00000000},
+       {0x0000a198, 0x00000000},
+       {0x0000a19c, 0x00000000},
+       {0x0000a1a0, 0x00000000},
+       {0x0000a1a4, 0x00000000},
+       {0x0000a1a8, 0x00000000},
+       {0x0000a1ac, 0x00000000},
+       {0x0000a1b0, 0x00000000},
+       {0x0000a1b4, 0x00000000},
+       {0x0000a1b8, 0x00000000},
+       {0x0000a1bc, 0x00000000},
+       {0x0000a1c0, 0x00000000},
+       {0x0000a1c4, 0x00000000},
+       {0x0000a1c8, 0x00000000},
+       {0x0000a1cc, 0x00000000},
+       {0x0000a1d0, 0x00000000},
+       {0x0000a1d4, 0x00000000},
+       {0x0000a1d8, 0x00000000},
+       {0x0000a1dc, 0x00000000},
+       {0x0000a1e0, 0x00000000},
+       {0x0000a1e4, 0x00000000},
+       {0x0000a1e8, 0x00000000},
+       {0x0000a1ec, 0x00000000},
+       {0x0000a1f0, 0x00000396},
+       {0x0000a1f4, 0x00000396},
+       {0x0000a1f8, 0x00000396},
+       {0x0000a1fc, 0x00000196},
+       {0x0000b000, 0x00010000},
+       {0x0000b004, 0x00030002},
+       {0x0000b008, 0x00050004},
+       {0x0000b00c, 0x00810080},
+       {0x0000b010, 0x00830082},
+       {0x0000b014, 0x01810180},
+       {0x0000b018, 0x01830182},
+       {0x0000b01c, 0x01850184},
+       {0x0000b020, 0x02810280},
+       {0x0000b024, 0x02830282},
+       {0x0000b028, 0x02850284},
+       {0x0000b02c, 0x02890288},
+       {0x0000b030, 0x028b028a},
+       {0x0000b034, 0x0388028c},
+       {0x0000b038, 0x038a0389},
+       {0x0000b03c, 0x038c038b},
+       {0x0000b040, 0x0390038d},
+       {0x0000b044, 0x03920391},
+       {0x0000b048, 0x03940393},
+       {0x0000b04c, 0x03960395},
+       {0x0000b050, 0x00000000},
+       {0x0000b054, 0x00000000},
+       {0x0000b058, 0x00000000},
+       {0x0000b05c, 0x00000000},
+       {0x0000b060, 0x00000000},
+       {0x0000b064, 0x00000000},
+       {0x0000b068, 0x00000000},
+       {0x0000b06c, 0x00000000},
+       {0x0000b070, 0x00000000},
+       {0x0000b074, 0x00000000},
+       {0x0000b078, 0x00000000},
+       {0x0000b07c, 0x00000000},
+       {0x0000b080, 0x23232323},
+       {0x0000b084, 0x21232323},
+       {0x0000b088, 0x19191c1e},
+       {0x0000b08c, 0x12141417},
+       {0x0000b090, 0x07070e0e},
+       {0x0000b094, 0x03030305},
+       {0x0000b098, 0x00000003},
+       {0x0000b09c, 0x00000000},
+       {0x0000b0a0, 0x00000000},
+       {0x0000b0a4, 0x00000000},
+       {0x0000b0a8, 0x00000000},
+       {0x0000b0ac, 0x00000000},
+       {0x0000b0b0, 0x00000000},
+       {0x0000b0b4, 0x00000000},
+       {0x0000b0b8, 0x00000000},
+       {0x0000b0bc, 0x00000000},
+       {0x0000b0c0, 0x003f0020},
+       {0x0000b0c4, 0x00400041},
+       {0x0000b0c8, 0x0140005f},
+       {0x0000b0cc, 0x0160015f},
+       {0x0000b0d0, 0x017e017f},
+       {0x0000b0d4, 0x02410242},
+       {0x0000b0d8, 0x025f0240},
+       {0x0000b0dc, 0x027f0260},
+       {0x0000b0e0, 0x0341027e},
+       {0x0000b0e4, 0x035f0340},
+       {0x0000b0e8, 0x037f0360},
+       {0x0000b0ec, 0x04400441},
+       {0x0000b0f0, 0x0460045f},
+       {0x0000b0f4, 0x0541047f},
+       {0x0000b0f8, 0x055f0540},
+       {0x0000b0fc, 0x057f0560},
+       {0x0000b100, 0x06400641},
+       {0x0000b104, 0x0660065f},
+       {0x0000b108, 0x067e067f},
+       {0x0000b10c, 0x07410742},
+       {0x0000b110, 0x075f0740},
+       {0x0000b114, 0x077f0760},
+       {0x0000b118, 0x07800781},
+       {0x0000b11c, 0x07a0079f},
+       {0x0000b120, 0x07c107bf},
+       {0x0000b124, 0x000007c0},
+       {0x0000b128, 0x00000000},
+       {0x0000b12c, 0x00000000},
+       {0x0000b130, 0x00000000},
+       {0x0000b134, 0x00000000},
+       {0x0000b138, 0x00000000},
+       {0x0000b13c, 0x00000000},
+       {0x0000b140, 0x003f0020},
+       {0x0000b144, 0x00400041},
+       {0x0000b148, 0x0140005f},
+       {0x0000b14c, 0x0160015f},
+       {0x0000b150, 0x017e017f},
+       {0x0000b154, 0x02410242},
+       {0x0000b158, 0x025f0240},
+       {0x0000b15c, 0x027f0260},
+       {0x0000b160, 0x0341027e},
+       {0x0000b164, 0x035f0340},
+       {0x0000b168, 0x037f0360},
+       {0x0000b16c, 0x04400441},
+       {0x0000b170, 0x0460045f},
+       {0x0000b174, 0x0541047f},
+       {0x0000b178, 0x055f0540},
+       {0x0000b17c, 0x057f0560},
+       {0x0000b180, 0x06400641},
+       {0x0000b184, 0x0660065f},
+       {0x0000b188, 0x067e067f},
+       {0x0000b18c, 0x07410742},
+       {0x0000b190, 0x075f0740},
+       {0x0000b194, 0x077f0760},
+       {0x0000b198, 0x07800781},
+       {0x0000b19c, 0x07a0079f},
+       {0x0000b1a0, 0x07c107bf},
+       {0x0000b1a4, 0x000007c0},
+       {0x0000b1a8, 0x00000000},
+       {0x0000b1ac, 0x00000000},
+       {0x0000b1b0, 0x00000000},
+       {0x0000b1b4, 0x00000000},
+       {0x0000b1b8, 0x00000000},
+       {0x0000b1bc, 0x00000000},
+       {0x0000b1c0, 0x00000000},
+       {0x0000b1c4, 0x00000000},
+       {0x0000b1c8, 0x00000000},
+       {0x0000b1cc, 0x00000000},
+       {0x0000b1d0, 0x00000000},
+       {0x0000b1d4, 0x00000000},
+       {0x0000b1d8, 0x00000000},
+       {0x0000b1dc, 0x00000000},
+       {0x0000b1e0, 0x00000000},
+       {0x0000b1e4, 0x00000000},
+       {0x0000b1e8, 0x00000000},
+       {0x0000b1ec, 0x00000000},
+       {0x0000b1f0, 0x00000396},
+       {0x0000b1f4, 0x00000396},
+       {0x0000b1f8, 0x00000396},
+       {0x0000b1fc, 0x00000196},
 };
 
 static const u32 ar9580_1p0_baseband_postamble[][5] = {
@@ -956,7 +1169,7 @@ static const u32 ar9580_1p0_baseband_postamble[][5] = {
        {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
        {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
        {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
-       {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
+       {0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982},
        {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
        {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
index 60a5da53668f54f9987692ccf7389794d13ea851..5e5d5cb2458c0a9c492b8ea74aaf83bcc91a4568 100644 (file)
@@ -459,6 +459,7 @@ void ath_check_ani(struct ath_softc *sc);
 int ath_update_survey_stats(struct ath_softc *sc);
 void ath_update_survey_nf(struct ath_softc *sc, int channel);
 void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
+void ath_ps_full_sleep(unsigned long data);
 
 /**********/
 /* BTCOEX */
@@ -570,6 +571,34 @@ static inline void ath_fill_led_pin(struct ath_softc *sc)
 }
 #endif
 
+/************************/
+/* Wake on Wireless LAN */
+/************************/
+
+#ifdef CONFIG_ATH9K_WOW
+void ath9k_init_wow(struct ieee80211_hw *hw);
+int ath9k_suspend(struct ieee80211_hw *hw,
+                 struct cfg80211_wowlan *wowlan);
+int ath9k_resume(struct ieee80211_hw *hw);
+void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled);
+#else
+static inline void ath9k_init_wow(struct ieee80211_hw *hw)
+{
+}
+static inline int ath9k_suspend(struct ieee80211_hw *hw,
+                               struct cfg80211_wowlan *wowlan)
+{
+       return 0;
+}
+static inline int ath9k_resume(struct ieee80211_hw *hw)
+{
+       return 0;
+}
+static inline void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
+{
+}
+#endif /* CONFIG_ATH9K_WOW */
+
 /*******************************/
 /* Antenna diversity/combining */
 /*******************************/
@@ -642,6 +671,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
 #define ATH9K_PCI_AR9565_1ANT     0x0080
 #define ATH9K_PCI_AR9565_2ANT     0x0100
 #define ATH9K_PCI_NO_PLL_PWRSAVE  0x0200
+#define ATH9K_PCI_KILLER          0x0400
 
 /*
  * Default cache line size, in bytes.
@@ -724,6 +754,7 @@ struct ath_softc {
        struct work_struct hw_check_work;
        struct work_struct hw_reset_work;
        struct completion paprd_complete;
+       wait_queue_head_t tx_wait;
 
        unsigned int hw_busy_count;
        unsigned long sc_flags;
@@ -760,6 +791,7 @@ struct ath_softc {
        struct delayed_work tx_complete_work;
        struct delayed_work hw_pll_work;
        struct timer_list rx_poll_timer;
+       struct timer_list sleep_timer;
 
 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
        struct ath_btcoex btcoex;
@@ -784,7 +816,7 @@ struct ath_softc {
        bool tx99_state;
        s16 tx99_power;
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ATH9K_WOW
        atomic_t wow_got_bmiss_intr;
        atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */
        u32 wow_intr_before_sleep;
@@ -947,10 +979,25 @@ struct fft_sample_ht20_40 {
        u8 data[SPECTRAL_HT20_40_NUM_BINS];
 } __packed;
 
-int ath9k_tx99_init(struct ath_softc *sc);
-void ath9k_tx99_deinit(struct ath_softc *sc);
+/********/
+/* TX99 */
+/********/
+
+#ifdef CONFIG_ATH9K_TX99
+void ath9k_tx99_init_debug(struct ath_softc *sc);
 int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
                    struct ath_tx_control *txctl);
+#else
+static inline void ath9k_tx99_init_debug(struct ath_softc *sc)
+{
+}
+static inline int ath9k_tx99_send(struct ath_softc *sc,
+                                 struct sk_buff *skb,
+                                 struct ath_tx_control *txctl)
+{
+       return 0;
+}
+#endif /* CONFIG_ATH9K_TX99 */
 
 void ath9k_tasklet(unsigned long data);
 int ath_cabq_update(struct ath_softc *);
@@ -967,6 +1014,9 @@ extern bool is_ath9k_unloaded;
 
 u8 ath9k_parse_mpdudensity(u8 mpdudensity);
 irqreturn_t ath_isr(int irq, void *dev);
+int ath_reset(struct ath_softc *sc);
+void ath_cancel_work(struct ath_softc *sc);
+void ath_restart_work(struct ath_softc *sc);
 int ath9k_init_device(u16 devid, struct ath_softc *sc,
                    const struct ath_bus_ops *bus_ops);
 void ath9k_deinit_device(struct ath_softc *sc);
index 83a2c59f680b0445173d25cc5ebccc2f7eb5777e..2f7dccfdb72784bf5c098a72ed703cf3abc0f2a2 100644 (file)
@@ -1778,111 +1778,6 @@ void ath9k_deinit_debug(struct ath_softc *sc)
        }
 }
 
-static ssize_t read_file_tx99(struct file *file, char __user *user_buf,
-                             size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[3];
-       unsigned int len;
-
-       len = sprintf(buf, "%d\n", sc->tx99_state);
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t write_file_tx99(struct file *file, const char __user *user_buf,
-                              size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       char buf[32];
-       bool start;
-       ssize_t len;
-       int r;
-
-       if (sc->nvifs > 1)
-               return -EOPNOTSUPP;
-
-       len = min(count, sizeof(buf) - 1);
-       if (copy_from_user(buf, user_buf, len))
-               return -EFAULT;
-
-       if (strtobool(buf, &start))
-               return -EINVAL;
-
-       if (start == sc->tx99_state) {
-               if (!start)
-                       return count;
-               ath_dbg(common, XMIT, "Resetting TX99\n");
-               ath9k_tx99_deinit(sc);
-       }
-
-       if (!start) {
-               ath9k_tx99_deinit(sc);
-               return count;
-       }
-
-       r = ath9k_tx99_init(sc);
-       if (r)
-               return r;
-
-       return count;
-}
-
-static const struct file_operations fops_tx99 = {
-       .read = read_file_tx99,
-       .write = write_file_tx99,
-       .open = simple_open,
-       .owner = THIS_MODULE,
-       .llseek = default_llseek,
-};
-
-static ssize_t read_file_tx99_power(struct file *file,
-                                   char __user *user_buf,
-                                   size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[32];
-       unsigned int len;
-
-       len = sprintf(buf, "%d (%d dBm)\n",
-                     sc->tx99_power,
-                     sc->tx99_power / 2);
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t write_file_tx99_power(struct file *file,
-                                    const char __user *user_buf,
-                                    size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       int r;
-       u8 tx_power;
-
-       r = kstrtou8_from_user(user_buf, count, 0, &tx_power);
-       if (r)
-               return r;
-
-       if (tx_power > MAX_RATE_POWER)
-               return -EINVAL;
-
-       sc->tx99_power = tx_power;
-
-       ath9k_ps_wakeup(sc);
-       ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power);
-       ath9k_ps_restore(sc);
-
-       return count;
-}
-
-static const struct file_operations fops_tx99_power = {
-       .read = read_file_tx99_power,
-       .write = write_file_tx99_power,
-       .open = simple_open,
-       .owner = THIS_MODULE,
-       .llseek = default_llseek,
-};
-
 int ath9k_init_debug(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
@@ -1899,6 +1794,7 @@ int ath9k_init_debug(struct ath_hw *ah)
 #endif
 
        ath9k_dfs_init_debug(sc);
+       ath9k_tx99_init_debug(sc);
 
        debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_dma);
@@ -1974,15 +1870,6 @@ int ath9k_init_debug(struct ath_hw *ah)
        debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_btcoex);
 #endif
-       if (config_enabled(CONFIG_ATH9K_TX99) &&
-           AR_SREV_9300_20_OR_LATER(ah)) {
-               debugfs_create_file("tx99", S_IRUSR | S_IWUSR,
-                                   sc->debug.debugfs_phy, sc,
-                                   &fops_tx99);
-               debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR,
-                                   sc->debug.debugfs_phy, sc,
-                                   &fops_tx99_power);
-       }
 
        return 0;
 }
index 8918035da3a3510c04ad45e106cebd3d267ad6e8..779d38a98a0e82c4a2e64cf676afef01fcbd1d59 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/time.h>
 #include <asm/unaligned.h>
 
 #include "hw.h"
@@ -453,7 +454,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
        }
 
        ah->config.rx_intr_mitigation = true;
-       ah->config.pcieSerDesWrite = true;
 
        /*
         * We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -1501,8 +1501,9 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
        int r;
 
        if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) {
-               band_switch = IS_CHAN_5GHZ(ah->curchan) != IS_CHAN_5GHZ(chan);
-               mode_diff = (chan->channelFlags != ah->curchan->channelFlags);
+               u32 flags_diff = chan->channelFlags ^ ah->curchan->channelFlags;
+               band_switch = !!(flags_diff & CHANNEL_5GHZ);
+               mode_diff = !!(flags_diff & ~CHANNEL_HT);
        }
 
        for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
@@ -1814,7 +1815,7 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
         * If cross-band fcc is not supoprted, bail out if channelFlags differ.
         */
        if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) &&
-           chan->channelFlags != ah->curchan->channelFlags)
+           ((chan->channelFlags ^ ah->curchan->channelFlags) & ~CHANNEL_HT))
                goto fail;
 
        if (!ath9k_hw_check_alive(ah))
@@ -1855,10 +1856,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                   struct ath9k_hw_cal_data *caldata, bool fastcc)
 {
        struct ath_common *common = ath9k_hw_common(ah);
+       struct timespec ts;
        u32 saveLedState;
        u32 saveDefAntenna;
        u32 macStaId1;
        u64 tsf = 0;
+       s64 usec = 0;
        int r;
        bool start_mci_reset = false;
        bool save_fullsleep = ah->chip_fullsleep;
@@ -1901,10 +1904,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
        macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
 
-       /* For chips on which RTC reset is done, save TSF before it gets cleared */
-       if (AR_SREV_9100(ah) ||
-           (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)))
-               tsf = ath9k_hw_gettsf64(ah);
+       /* Save TSF before chip reset, a cold reset clears it */
+       tsf = ath9k_hw_gettsf64(ah);
+       getrawmonotonic(&ts);
+       usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000;
 
        saveLedState = REG_READ(ah, AR_CFG_LED) &
                (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
@@ -1937,8 +1940,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        }
 
        /* Restore TSF */
-       if (tsf)
-               ath9k_hw_settsf64(ah, tsf);
+       getrawmonotonic(&ts);
+       usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000 - usec;
+       ath9k_hw_settsf64(ah, tsf + usec);
 
        if (AR_SREV_9280_20_OR_LATER(ah))
                REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
index a2c9a5dbac6b0317fba5131ee212d3ef9292c77a..e50843600989342d6c778f361e82fd1efaa212e0 100644 (file)
@@ -283,7 +283,6 @@ struct ath9k_ops_config {
        int additional_swba_backoff;
        int ack_6mb;
        u32 cwm_ignore_extcca;
-       bool pcieSerDesWrite;
        u8 pcie_clock_req;
        u32 pcie_waen;
        u8 analog_shiftreg;
@@ -921,7 +920,7 @@ struct ath_hw {
        /* Enterprise mode cap */
        u32 ent_mode;
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ATH9K_WOW
        u32 wow_event_mask;
 #endif
        bool is_clk_25mhz;
@@ -1127,7 +1126,7 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
 #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
 
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ATH9K_WOW
 const char *ath9k_hw_wow_event_to_string(u32 wow_event);
 void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
                                u8 *user_mask, int pattern_count,
index 710192ed27ed3118656f1a3b08bc41ec92c649a1..8f4c1674b76e2a2f1c301d9e3796a4d3ffea1906 100644 (file)
@@ -589,6 +589,9 @@ static void ath9k_init_platform(struct ath_softc *sc)
        if (sc->driver_data & ATH9K_PCI_AR9565_2ANT)
                ath_info(common, "WB335 2-ANT card detected\n");
 
+       if (sc->driver_data & ATH9K_PCI_KILLER)
+               ath_info(common, "Killer Wireless card detected\n");
+
        /*
         * Some WB335 cards do not support antenna diversity. Since
         * we use a hardcoded value for AR9565 instead of using the
@@ -688,6 +691,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
        common = ath9k_hw_common(ah);
        sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
        sc->tx99_power = MAX_RATE_POWER + 1;
+       init_waitqueue_head(&sc->tx_wait);
 
        if (!pdata) {
                ah->ah_flags |= AH_USE_EEPROM;
@@ -735,6 +739,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
        tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
                     (unsigned long)sc);
 
+       setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc);
        INIT_WORK(&sc->hw_reset_work, ath_reset_work);
        INIT_WORK(&sc->hw_check_work, ath_hw_check);
        INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
@@ -873,15 +878,6 @@ static const struct ieee80211_iface_combination if_comb[] = {
        }
 };
 
-#ifdef CONFIG_PM
-static const struct wiphy_wowlan_support ath9k_wowlan_support = {
-       .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
-       .n_patterns = MAX_NUM_USER_PATTERN,
-       .pattern_min_len = 1,
-       .pattern_max_len = MAX_PATTERN_SIZE,
-};
-#endif
-
 void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
        struct ath_hw *ah = sc->sc_ah;
@@ -931,16 +927,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
        hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
 
-#ifdef CONFIG_PM_SLEEP
-       if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
-           (sc->driver_data & ATH9K_PCI_WOW) &&
-           device_can_wakeup(sc->dev))
-               hw->wiphy->wowlan = &ath9k_wowlan_support;
-
-       atomic_set(&sc->wow_sleep_proc_intr, -1);
-       atomic_set(&sc->wow_got_bmiss_intr, -1);
-#endif
-
        hw->queues = 4;
        hw->max_rates = 4;
        hw->channel_change_time = 5000;
@@ -966,6 +952,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
                hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
                        &sc->sbands[IEEE80211_BAND_5GHZ];
 
+       ath9k_init_wow(hw);
        ath9k_reload_chainmask_settings(sc);
 
        SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
@@ -1064,6 +1051,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
                if (ATH_TXQ_SETUP(sc, i))
                        ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 
+       del_timer_sync(&sc->sleep_timer);
        ath9k_hw_deinit(sc->sc_ah);
        if (sc->dfs_detector != NULL)
                sc->dfs_detector->exit(sc->dfs_detector);
index 74f452c7b1667c47a65506a077042f2b0668c3a8..b1dcf89138d30d4ce8899e9a117ee96ac29212e5 100644 (file)
@@ -82,6 +82,22 @@ static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
        return ret;
 }
 
+void ath_ps_full_sleep(unsigned long data)
+{
+       struct ath_softc *sc = (struct ath_softc *) data;
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       bool reset;
+
+       spin_lock(&common->cc_lock);
+       ath_hw_cycle_counters_update(common);
+       spin_unlock(&common->cc_lock);
+
+       ath9k_hw_setrxabort(sc->sc_ah, 1);
+       ath9k_hw_stopdmarecv(sc->sc_ah, &reset);
+
+       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
+}
+
 void ath9k_ps_wakeup(struct ath_softc *sc)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -92,6 +108,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
        if (++sc->ps_usecount != 1)
                goto unlock;
 
+       del_timer_sync(&sc->sleep_timer);
        power_mode = sc->sc_ah->power_mode;
        ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
 
@@ -117,17 +134,17 @@ void ath9k_ps_restore(struct ath_softc *sc)
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        enum ath9k_power_mode mode;
        unsigned long flags;
-       bool reset;
 
        spin_lock_irqsave(&sc->sc_pm_lock, flags);
        if (--sc->ps_usecount != 0)
                goto unlock;
 
        if (sc->ps_idle) {
-               ath9k_hw_setrxabort(sc->sc_ah, 1);
-               ath9k_hw_stopdmarecv(sc->sc_ah, &reset);
-               mode = ATH9K_PM_FULL_SLEEP;
-       } else if (sc->ps_enabled &&
+               mod_timer(&sc->sleep_timer, jiffies + HZ / 10);
+               goto unlock;
+       }
+
+       if (sc->ps_enabled &&
                   !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
                                     PS_WAIT_FOR_CAB |
                                     PS_WAIT_FOR_PSPOLL_DATA |
@@ -163,13 +180,13 @@ static void __ath_cancel_work(struct ath_softc *sc)
 #endif
 }
 
-static void ath_cancel_work(struct ath_softc *sc)
+void ath_cancel_work(struct ath_softc *sc)
 {
        __ath_cancel_work(sc);
        cancel_work_sync(&sc->hw_reset_work);
 }
 
-static void ath_restart_work(struct ath_softc *sc)
+void ath_restart_work(struct ath_softc *sc)
 {
        ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
 
@@ -487,6 +504,8 @@ void ath9k_tasklet(unsigned long data)
                        ath_tx_edma_tasklet(sc);
                else
                        ath_tx_tasklet(sc);
+
+               wake_up(&sc->tx_wait);
        }
 
        ath9k_btcoex_handle_interrupt(sc, status);
@@ -579,7 +598,8 @@ irqreturn_t ath_isr(int irq, void *dev)
 
                goto chip_reset;
        }
-#ifdef CONFIG_PM_SLEEP
+
+#ifdef CONFIG_ATH9K_WOW
        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");
@@ -588,6 +608,8 @@ irqreturn_t ath_isr(int irq, void *dev)
                }
        }
 #endif
+
+
        if (status & ATH9K_INT_SWBA)
                tasklet_schedule(&sc->bcon_tasklet);
 
@@ -627,7 +649,7 @@ chip_reset:
 #undef SCHED_INTR
 }
 
-static int ath_reset(struct ath_softc *sc)
+int ath_reset(struct ath_softc *sc)
 {
        int r;
 
@@ -1817,13 +1839,31 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
        mutex_unlock(&sc->mutex);
 }
 
+static bool ath9k_has_tx_pending(struct ath_softc *sc)
+{
+       int i, npend;
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (!ATH_TXQ_SETUP(sc, i))
+                       continue;
+
+               if (!sc->tx.txq[i].axq_depth)
+                       continue;
+
+               npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
+               if (npend)
+                       break;
+       }
+
+       return !!npend;
+}
+
 static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
 {
        struct ath_softc *sc = hw->priv;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       int timeout = 200; /* ms */
-       int i, j;
+       int timeout = HZ / 5; /* 200 ms */
        bool drain_txq;
 
        mutex_lock(&sc->mutex);
@@ -1841,25 +1881,9 @@ static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
                return;
        }
 
-       for (j = 0; j < timeout; j++) {
-               bool npend = false;
-
-               if (j)
-                       usleep_range(1000, 2000);
-
-               for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-                       if (!ATH_TXQ_SETUP(sc, i))
-                               continue;
-
-                       npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
-
-                       if (npend)
-                               break;
-               }
-
-               if (!npend)
-                   break;
-       }
+       if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc),
+                              timeout) > 0)
+               drop = false;
 
        if (drop) {
                ath9k_ps_wakeup(sc);
@@ -2021,333 +2045,6 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
        return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-
-static void ath9k_wow_map_triggers(struct ath_softc *sc,
-                                  struct cfg80211_wowlan *wowlan,
-                                  u32 *wow_triggers)
-{
-       if (wowlan->disconnect)
-               *wow_triggers |= AH_WOW_LINK_CHANGE |
-                                AH_WOW_BEACON_MISS;
-       if (wowlan->magic_pkt)
-               *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
-
-       if (wowlan->n_patterns)
-               *wow_triggers |= AH_WOW_USER_PATTERN_EN;
-
-       sc->wow_enabled = *wow_triggers;
-
-}
-
-static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-       int pattern_count = 0;
-       int i, byte_cnt;
-       u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
-       u8 dis_deauth_mask[MAX_PATTERN_SIZE];
-
-       memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
-       memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
-
-       /*
-        * Create Dissassociate / Deauthenticate packet filter
-        *
-        *     2 bytes        2 byte    6 bytes   6 bytes  6 bytes
-        *  +--------------+----------+---------+--------+--------+----
-        *  + Frame Control+ Duration +   DA    +  SA    +  BSSID +
-        *  +--------------+----------+---------+--------+--------+----
-        *
-        * The above is the management frame format for disassociate/
-        * deauthenticate pattern, from this we need to match the first byte
-        * of 'Frame Control' and DA, SA, and BSSID fields
-        * (skipping 2nd byte of FC and Duration feild.
-        *
-        * Disassociate pattern
-        * --------------------
-        * Frame control = 00 00 1010
-        * DA, SA, BSSID = x:x:x:x:x:x
-        * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
-        *                          | x:x:x:x:x:x  -- 22 bytes
-        *
-        * Deauthenticate pattern
-        * ----------------------
-        * Frame control = 00 00 1100
-        * DA, SA, BSSID = x:x:x:x:x:x
-        * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
-        *                          | x:x:x:x:x:x  -- 22 bytes
-        */
-
-       /* Create Disassociate Pattern first */
-
-       byte_cnt = 0;
-
-       /* Fill out the mask with all FF's */
-
-       for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
-               dis_deauth_mask[i] = 0xff;
-
-       /* copy the first byte of frame control field */
-       dis_deauth_pattern[byte_cnt] = 0xa0;
-       byte_cnt++;
-
-       /* skip 2nd byte of frame control and Duration field */
-       byte_cnt += 3;
-
-       /*
-        * need not match the destination mac address, it can be a broadcast
-        * mac address or an unicast to this station
-        */
-       byte_cnt += 6;
-
-       /* copy the source mac address */
-       memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
-
-       byte_cnt += 6;
-
-       /* copy the bssid, its same as the source mac address */
-
-       memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
-
-       /* Create Disassociate pattern mask */
-
-       dis_deauth_mask[0] = 0xfe;
-       dis_deauth_mask[1] = 0x03;
-       dis_deauth_mask[2] = 0xc0;
-
-       ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
-
-       ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
-                                  pattern_count, byte_cnt);
-
-       pattern_count++;
-       /*
-        * for de-authenticate pattern, only the first byte of the frame
-        * control field gets changed from 0xA0 to 0xC0
-        */
-       dis_deauth_pattern[0] = 0xC0;
-
-       ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
-                                  pattern_count, byte_cnt);
-
-}
-
-static void ath9k_wow_add_pattern(struct ath_softc *sc,
-                                 struct cfg80211_wowlan *wowlan)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath9k_wow_pattern *wow_pattern = NULL;
-       struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
-       int mask_len;
-       s8 i = 0;
-
-       if (!wowlan->n_patterns)
-               return;
-
-       /*
-        * Add the new user configured patterns
-        */
-       for (i = 0; i < wowlan->n_patterns; i++) {
-
-               wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
-
-               if (!wow_pattern)
-                       return;
-
-               /*
-                * TODO: convert the generic user space pattern to
-                * appropriate chip specific/802.11 pattern.
-                */
-
-               mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
-               memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
-               memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
-               memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
-                      patterns[i].pattern_len);
-               memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
-               wow_pattern->pattern_len = patterns[i].pattern_len;
-
-               /*
-                * just need to take care of deauth and disssoc pattern,
-                * make sure we don't overwrite them.
-                */
-
-               ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
-                                          wow_pattern->mask_bytes,
-                                          i + 2,
-                                          wow_pattern->pattern_len);
-               kfree(wow_pattern);
-
-       }
-
-}
-
-static int ath9k_suspend(struct ieee80211_hw *hw,
-                        struct cfg80211_wowlan *wowlan)
-{
-       struct ath_softc *sc = hw->priv;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-       u32 wow_triggers_enabled = 0;
-       int ret = 0;
-
-       mutex_lock(&sc->mutex);
-
-       ath_cancel_work(sc);
-       ath_stop_ani(sc);
-       del_timer_sync(&sc->rx_poll_timer);
-
-       if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
-               ath_dbg(common, ANY, "Device not present\n");
-               ret = -EINVAL;
-               goto fail_wow;
-       }
-
-       if (WARN_ON(!wowlan)) {
-               ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
-               ret = -EINVAL;
-               goto fail_wow;
-       }
-
-       if (!device_can_wakeup(sc->dev)) {
-               ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
-               ret = 1;
-               goto fail_wow;
-       }
-
-       /*
-        * none of the sta vifs are associated
-        * and we are not currently handling multivif
-        * cases, for instance we have to seperately
-        * configure 'keep alive frame' for each
-        * STA.
-        */
-
-       if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
-               ath_dbg(common, WOW, "None of the STA vifs are associated\n");
-               ret = 1;
-               goto fail_wow;
-       }
-
-       if (sc->nvifs > 1) {
-               ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
-               ret = 1;
-               goto fail_wow;
-       }
-
-       ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
-
-       ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
-               wow_triggers_enabled);
-
-       ath9k_ps_wakeup(sc);
-
-       ath9k_stop_btcoex(sc);
-
-       /*
-        * Enable wake up on recieving disassoc/deauth
-        * frame by default.
-        */
-       ath9k_wow_add_disassoc_deauth_pattern(sc);
-
-       if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
-               ath9k_wow_add_pattern(sc, wowlan);
-
-       spin_lock_bh(&sc->sc_pcu_lock);
-       /*
-        * To avoid false wake, we enable beacon miss interrupt only
-        * when we go to sleep. We save the current interrupt mask
-        * so we can restore it after the system wakes up
-        */
-       sc->wow_intr_before_sleep = ah->imask;
-       ah->imask &= ~ATH9K_INT_GLOBAL;
-       ath9k_hw_disable_interrupts(ah);
-       ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
-       ath9k_hw_set_interrupts(ah);
-       ath9k_hw_enable_interrupts(ah);
-
-       spin_unlock_bh(&sc->sc_pcu_lock);
-
-       /*
-        * we can now sync irq and kill any running tasklets, since we already
-        * disabled interrupts and not holding a spin lock
-        */
-       synchronize_irq(sc->irq);
-       tasklet_kill(&sc->intr_tq);
-
-       ath9k_hw_wow_enable(ah, wow_triggers_enabled);
-
-       ath9k_ps_restore(sc);
-       ath_dbg(common, ANY, "WoW enabled in ath9k\n");
-       atomic_inc(&sc->wow_sleep_proc_intr);
-
-fail_wow:
-       mutex_unlock(&sc->mutex);
-       return ret;
-}
-
-static int ath9k_resume(struct ieee80211_hw *hw)
-{
-       struct ath_softc *sc = hw->priv;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-       u32 wow_status;
-
-       mutex_lock(&sc->mutex);
-
-       ath9k_ps_wakeup(sc);
-
-       spin_lock_bh(&sc->sc_pcu_lock);
-
-       ath9k_hw_disable_interrupts(ah);
-       ah->imask = sc->wow_intr_before_sleep;
-       ath9k_hw_set_interrupts(ah);
-       ath9k_hw_enable_interrupts(ah);
-
-       spin_unlock_bh(&sc->sc_pcu_lock);
-
-       wow_status = ath9k_hw_wow_wakeup(ah);
-
-       if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
-               /*
-                * some devices may not pick beacon miss
-                * as the reason they woke up so we add
-                * that here for that shortcoming.
-                */
-               wow_status |= AH_WOW_BEACON_MISS;
-               atomic_dec(&sc->wow_got_bmiss_intr);
-               ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
-       }
-
-       atomic_dec(&sc->wow_sleep_proc_intr);
-
-       if (wow_status) {
-               ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
-                       ath9k_hw_wow_event_to_string(wow_status), wow_status);
-       }
-
-       ath_restart_work(sc);
-       ath9k_start_btcoex(sc);
-
-       ath9k_ps_restore(sc);
-       mutex_unlock(&sc->mutex);
-
-       return 0;
-}
-
-static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
-{
-       struct ath_softc *sc = hw->priv;
-
-       mutex_lock(&sc->mutex);
-       device_init_wakeup(sc->dev, 1);
-       device_set_wakeup_enable(sc->dev, enabled);
-       mutex_unlock(&sc->mutex);
-}
-
-#endif
 static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
 {
        struct ath_softc *sc = hw->priv;
@@ -2373,134 +2070,6 @@ static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw,
        sc->csa_vif = vif;
 }
 
-static void ath9k_tx99_stop(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-
-       ath_drain_all_txq(sc);
-       ath_startrecv(sc);
-
-       ath9k_hw_set_interrupts(ah);
-       ath9k_hw_enable_interrupts(ah);
-
-       ieee80211_wake_queues(sc->hw);
-
-       kfree_skb(sc->tx99_skb);
-       sc->tx99_skb = NULL;
-       sc->tx99_state = false;
-
-       ath9k_hw_tx99_stop(sc->sc_ah);
-       ath_dbg(common, XMIT, "TX99 stopped\n");
-}
-
-static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
-{
-       static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
-                              0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
-                              0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
-                              0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
-                              0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
-                              0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
-                              0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
-                              0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
-       u32 len = 1200;
-       struct ieee80211_hw *hw = sc->hw;
-       struct ieee80211_hdr *hdr;
-       struct ieee80211_tx_info *tx_info;
-       struct sk_buff *skb;
-
-       skb = alloc_skb(len, GFP_KERNEL);
-       if (!skb)
-               return NULL;
-
-       skb_put(skb, len);
-
-       memset(skb->data, 0, len);
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-       hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA);
-       hdr->duration_id = 0;
-
-       memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
-       memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
-       memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
-
-       hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
-
-       tx_info = IEEE80211_SKB_CB(skb);
-       memset(tx_info, 0, sizeof(*tx_info));
-       tx_info->band = hw->conf.chandef.chan->band;
-       tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
-       tx_info->control.vif = sc->tx99_vif;
-
-       memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data));
-
-       return skb;
-}
-
-void ath9k_tx99_deinit(struct ath_softc *sc)
-{
-       ath_reset(sc);
-
-       ath9k_ps_wakeup(sc);
-       ath9k_tx99_stop(sc);
-       ath9k_ps_restore(sc);
-}
-
-int ath9k_tx99_init(struct ath_softc *sc)
-{
-       struct ieee80211_hw *hw = sc->hw;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-       struct ath_tx_control txctl;
-       int r;
-
-       if (sc->sc_flags & SC_OP_INVALID) {
-               ath_err(common,
-                       "driver is in invalid state unable to use TX99");
-               return -EINVAL;
-       }
-
-       sc->tx99_skb = ath9k_build_tx99_skb(sc);
-       if (!sc->tx99_skb)
-               return -ENOMEM;
-
-       memset(&txctl, 0, sizeof(txctl));
-       txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
-
-       ath_reset(sc);
-
-       ath9k_ps_wakeup(sc);
-
-       ath9k_hw_disable_interrupts(ah);
-       atomic_set(&ah->intr_ref_cnt, -1);
-       ath_drain_all_txq(sc);
-       ath_stoprecv(sc);
-
-       sc->tx99_state = true;
-
-       ieee80211_stop_queues(hw);
-
-       if (sc->tx99_power == MAX_RATE_POWER + 1)
-               sc->tx99_power = MAX_RATE_POWER;
-
-       ath9k_hw_tx99_set_txpower(ah, sc->tx99_power);
-       r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl);
-       if (r) {
-               ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n");
-               return r;
-       }
-
-       ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n",
-               sc->tx99_power,
-               sc->tx99_power / 2);
-
-       /* We leave the harware awake as it will be chugging on */
-
-       return 0;
-}
-
 struct ieee80211_ops ath9k_ops = {
        .tx                 = ath9k_tx,
        .start              = ath9k_start,
@@ -2531,7 +2100,7 @@ struct ieee80211_ops ath9k_ops = {
        .set_antenna        = ath9k_set_antenna,
        .get_antenna        = ath9k_get_antenna,
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ATH9K_WOW
        .suspend            = ath9k_suspend,
        .resume             = ath9k_resume,
        .set_wakeup         = ath9k_set_wakeup,
index b5656fce4ff5f042b9053258e31c9b503802d217..e9a585758941fc9305fa859bab091992eb9946a8 100644 (file)
@@ -87,6 +87,19 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
        { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
        { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI   */
        { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
+
+       /* Killer Wireless (3x3) */
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+                        0x0030,
+                        0x1A56,
+                        0x2000),
+         .driver_data = ATH9K_PCI_KILLER },
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+                        0x0030,
+                        0x1A56,
+                        0x2001),
+         .driver_data = ATH9K_PCI_KILLER },
+
        { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E  AR9300 */
 
        /* PCI-E CUS198 */
@@ -354,6 +367,13 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
                         0x1783),
          .driver_data = ATH9K_PCI_WOW },
 
+       /* Killer Wireless (2x2) */
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+                        0x0030,
+                        0x1A56,
+                        0x2003),
+         .driver_data = ATH9K_PCI_KILLER },
+
        { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E  AR9462 */
        { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E  AR1111/AR9485 */
 
@@ -446,6 +466,11 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
                         0x11AD, /* LITEON */
                         0x0662),
          .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+                        0x0036,
+                        0x11AD, /* LITEON */
+                        0x0682),
+         .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
        { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
                         0x0036,
                         PCI_VENDOR_ID_AZWAVE,
@@ -456,6 +481,11 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
                         PCI_VENDOR_ID_LENOVO,
                         0x3026),
          .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+                        0x0036,
+                        PCI_VENDOR_ID_LENOVO,
+                        0x4026),
+         .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
        { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
                         0x0036,
                         PCI_VENDOR_ID_HP,
@@ -466,6 +496,11 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
                         PCI_VENDOR_ID_HP,
                         0x217F),
          .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+                        0x0036,
+                        PCI_VENDOR_ID_HP,
+                        0x2005),
+         .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
        { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
                         0x0036,
                         PCI_VENDOR_ID_DELL,
@@ -545,6 +580,16 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
                         0x185F, /* WNC */
                         0x3027),
          .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+                        0x0036,
+                        0x185F, /* WNC */
+                        0xA120),
+         .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+                        0x0036,
+                        PCI_VENDOR_ID_FOXCONN,
+                        0xE07F),
+         .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
 
        /* PCI-E AR9565 (WB335) */
        { PCI_VDEVICE(ATHEROS, 0x0036),
index a13b2d143d9eb31411fcb0f504a91c1ba1026e21..259a4b3077077fa8d4e90625ea6a7fb362990489 100644 (file)
 #define AR_SREV_REVISION_9462_21       3
 #define AR_SREV_VERSION_9565            0x2C0
 #define AR_SREV_REVISION_9565_10        0
+#define AR_SREV_REVISION_9565_101       1
+#define AR_SREV_REVISION_9565_11        2
 #define AR_SREV_VERSION_9550           0x400
 
 #define AR_SREV_5416(_ah) \
 
 #define AR_SREV_9565(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
-
 #define AR_SREV_9565_10(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
         ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10))
+#define AR_SREV_9565_101(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_101))
+#define AR_SREV_9565_11(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_11))
+#define AR_SREV_9565_11_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
+        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9565_11))
 
 #define AR_SREV_9550(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550))
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
new file mode 100644 (file)
index 0000000..57d7757
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2013 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 "ath9k.h"
+
+static void ath9k_tx99_stop(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       ath_drain_all_txq(sc);
+       ath_startrecv(sc);
+
+       ath9k_hw_set_interrupts(ah);
+       ath9k_hw_enable_interrupts(ah);
+
+       ieee80211_wake_queues(sc->hw);
+
+       kfree_skb(sc->tx99_skb);
+       sc->tx99_skb = NULL;
+       sc->tx99_state = false;
+
+       ath9k_hw_tx99_stop(sc->sc_ah);
+       ath_dbg(common, XMIT, "TX99 stopped\n");
+}
+
+static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
+{
+       static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
+                              0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
+                              0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
+                              0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
+                              0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
+                              0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
+                              0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
+                              0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
+       u32 len = 1200;
+       struct ieee80211_hw *hw = sc->hw;
+       struct ieee80211_hdr *hdr;
+       struct ieee80211_tx_info *tx_info;
+       struct sk_buff *skb;
+
+       skb = alloc_skb(len, GFP_KERNEL);
+       if (!skb)
+               return NULL;
+
+       skb_put(skb, len);
+
+       memset(skb->data, 0, len);
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+       hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA);
+       hdr->duration_id = 0;
+
+       memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
+       memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
+       memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
+
+       hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
+
+       tx_info = IEEE80211_SKB_CB(skb);
+       memset(tx_info, 0, sizeof(*tx_info));
+       tx_info->band = hw->conf.chandef.chan->band;
+       tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
+       tx_info->control.vif = sc->tx99_vif;
+       tx_info->control.rates[0].count = 1;
+
+       memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data));
+
+       return skb;
+}
+
+static void ath9k_tx99_deinit(struct ath_softc *sc)
+{
+       ath_reset(sc);
+
+       ath9k_ps_wakeup(sc);
+       ath9k_tx99_stop(sc);
+       ath9k_ps_restore(sc);
+}
+
+static int ath9k_tx99_init(struct ath_softc *sc)
+{
+       struct ieee80211_hw *hw = sc->hw;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath_tx_control txctl;
+       int r;
+
+       if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
+               ath_err(common,
+                       "driver is in invalid state unable to use TX99");
+               return -EINVAL;
+       }
+
+       sc->tx99_skb = ath9k_build_tx99_skb(sc);
+       if (!sc->tx99_skb)
+               return -ENOMEM;
+
+       memset(&txctl, 0, sizeof(txctl));
+       txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
+
+       ath_reset(sc);
+
+       ath9k_ps_wakeup(sc);
+
+       ath9k_hw_disable_interrupts(ah);
+       atomic_set(&ah->intr_ref_cnt, -1);
+       ath_drain_all_txq(sc);
+       ath_stoprecv(sc);
+
+       sc->tx99_state = true;
+
+       ieee80211_stop_queues(hw);
+
+       if (sc->tx99_power == MAX_RATE_POWER + 1)
+               sc->tx99_power = MAX_RATE_POWER;
+
+       ath9k_hw_tx99_set_txpower(ah, sc->tx99_power);
+       r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl);
+       if (r) {
+               ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n");
+               return r;
+       }
+
+       ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n",
+               sc->tx99_power,
+               sc->tx99_power / 2);
+
+       /* We leave the harware awake as it will be chugging on */
+
+       return 0;
+}
+
+static ssize_t read_file_tx99(struct file *file, char __user *user_buf,
+                             size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[3];
+       unsigned int len;
+
+       len = sprintf(buf, "%d\n", sc->tx99_state);
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_tx99(struct file *file, const char __user *user_buf,
+                              size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       char buf[32];
+       bool start;
+       ssize_t len;
+       int r;
+
+       if (sc->nvifs > 1)
+               return -EOPNOTSUPP;
+
+       len = min(count, sizeof(buf) - 1);
+       if (copy_from_user(buf, user_buf, len))
+               return -EFAULT;
+
+       if (strtobool(buf, &start))
+               return -EINVAL;
+
+       if (start == sc->tx99_state) {
+               if (!start)
+                       return count;
+               ath_dbg(common, XMIT, "Resetting TX99\n");
+               ath9k_tx99_deinit(sc);
+       }
+
+       if (!start) {
+               ath9k_tx99_deinit(sc);
+               return count;
+       }
+
+       r = ath9k_tx99_init(sc);
+       if (r)
+               return r;
+
+       return count;
+}
+
+static const struct file_operations fops_tx99 = {
+       .read = read_file_tx99,
+       .write = write_file_tx99,
+       .open = simple_open,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
+
+static ssize_t read_file_tx99_power(struct file *file,
+                                   char __user *user_buf,
+                                   size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[32];
+       unsigned int len;
+
+       len = sprintf(buf, "%d (%d dBm)\n",
+                     sc->tx99_power,
+                     sc->tx99_power / 2);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_tx99_power(struct file *file,
+                                    const char __user *user_buf,
+                                    size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       int r;
+       u8 tx_power;
+
+       r = kstrtou8_from_user(user_buf, count, 0, &tx_power);
+       if (r)
+               return r;
+
+       if (tx_power > MAX_RATE_POWER)
+               return -EINVAL;
+
+       sc->tx99_power = tx_power;
+
+       ath9k_ps_wakeup(sc);
+       ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power);
+       ath9k_ps_restore(sc);
+
+       return count;
+}
+
+static const struct file_operations fops_tx99_power = {
+       .read = read_file_tx99_power,
+       .write = write_file_tx99_power,
+       .open = simple_open,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
+
+void ath9k_tx99_init_debug(struct ath_softc *sc)
+{
+       if (!AR_SREV_9300_20_OR_LATER(sc->sc_ah))
+               return;
+
+       debugfs_create_file("tx99", S_IRUSR | S_IWUSR,
+                           sc->debug.debugfs_phy, sc,
+                           &fops_tx99);
+       debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR,
+                           sc->debug.debugfs_phy, sc,
+                           &fops_tx99_power);
+}
index 81c88dd606dcd960f43e740b9af8cffcdc25778a..f1cde81bb7a2573f1905c2725c29c176da7013f0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ * Copyright (c) 2013 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
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <linux/export.h>
 #include "ath9k.h"
-#include "reg.h"
-#include "hw-ops.h"
 
-const char *ath9k_hw_wow_event_to_string(u32 wow_event)
-{
-       if (wow_event & AH_WOW_MAGIC_PATTERN_EN)
-               return "Magic pattern";
-       if (wow_event & AH_WOW_USER_PATTERN_EN)
-               return "User pattern";
-       if (wow_event & AH_WOW_LINK_CHANGE)
-               return "Link change";
-       if (wow_event & AH_WOW_BEACON_MISS)
-               return "Beacon miss";
-
-       return  "unknown reason";
-}
-EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
+static const struct wiphy_wowlan_support ath9k_wowlan_support = {
+       .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
+       .n_patterns = MAX_NUM_USER_PATTERN,
+       .pattern_min_len = 1,
+       .pattern_max_len = MAX_PATTERN_SIZE,
+};
 
-static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
+static void ath9k_wow_map_triggers(struct ath_softc *sc,
+                                  struct cfg80211_wowlan *wowlan,
+                                  u32 *wow_triggers)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
+       if (wowlan->disconnect)
+               *wow_triggers |= AH_WOW_LINK_CHANGE |
+                                AH_WOW_BEACON_MISS;
+       if (wowlan->magic_pkt)
+               *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
 
-       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+       if (wowlan->n_patterns)
+               *wow_triggers |= AH_WOW_USER_PATTERN_EN;
 
-       /* set rx disable bit */
-       REG_WRITE(ah, AR_CR, AR_CR_RXD);
-
-       if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
-               ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
-                       REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
-               return;
-       }
+       sc->wow_enabled = *wow_triggers;
 
-       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
 }
 
-static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
+static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
 {
+       struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN];
-       u32 ctl[13] = {0};
-       u32 data_word[KAL_NUM_DATA_WORDS];
-       u8 i;
-       u32 wow_ka_data_word0;
-
-       memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
-       memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
-
-       /* set the transmit buffer */
-       ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
-       ctl[1] = 0;
-       ctl[3] = 0xb;   /* OFDM_6M hardware value for this rate */
-       ctl[4] = 0;
-       ctl[7] = (ah->txchainmask) << 2;
-       ctl[2] = 0xf << 16; /* tx_tries 0 */
-
-       for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
-               REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
-
-       REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
-
-       data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
-                      (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
-       data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
-                      (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
-       data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) |
-                      (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
-       data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) |
-                      (sta_mac_addr[3] << 8) | (sta_mac_addr[2]);
-       data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
-                      (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
-       data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
-
-       if (AR_SREV_9462_20(ah)) {
-               /* AR9462 2.0 has an extra descriptor word (time based
-                * discard) compared to other chips */
-               REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
-               wow_ka_data_word0 = AR_WOW_TXBUF(13);
-       } else {
-               wow_ka_data_word0 = AR_WOW_TXBUF(12);
-       }
-
-       for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
-               REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
-
-}
-
-void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
-                               u8 *user_mask, int pattern_count,
-                               int pattern_len)
-{
-       int i;
-       u32 pattern_val, mask_val;
-       u32 set, clr;
+       int pattern_count = 0;
+       int i, byte_cnt;
+       u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
+       u8 dis_deauth_mask[MAX_PATTERN_SIZE];
 
-       /* FIXME: should check count by querying the hardware capability */
-       if (pattern_count >= MAX_NUM_PATTERN)
-               return;
-
-       REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
-
-       /* set the registers for pattern */
-       for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
-               memcpy(&pattern_val, user_pattern, 4);
-               REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
-                         pattern_val);
-               user_pattern += 4;
-       }
-
-       /* set the registers for mask */
-       for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
-               memcpy(&mask_val, user_mask, 4);
-               REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
-               user_mask += 4;
-       }
+       memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
+       memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
 
-       /* set the pattern length to be matched
+       /*
+        * Create Dissassociate / Deauthenticate packet filter
+        *
+        *     2 bytes        2 byte    6 bytes   6 bytes  6 bytes
+        *  +--------------+----------+---------+--------+--------+----
+        *  + Frame Control+ Duration +   DA    +  SA    +  BSSID +
+        *  +--------------+----------+---------+--------+--------+----
         *
-        * AR_WOW_LENGTH1_REG1
-        * bit 31:24 pattern 0 length
-        * bit 23:16 pattern 1 length
-        * bit 15:8 pattern 2 length
-        * bit 7:0 pattern 3 length
+        * The above is the management frame format for disassociate/
+        * deauthenticate pattern, from this we need to match the first byte
+        * of 'Frame Control' and DA, SA, and BSSID fields
+        * (skipping 2nd byte of FC and Duration feild.
         *
-        * AR_WOW_LENGTH1_REG2
-        * bit 31:24 pattern 4 length
-        * bit 23:16 pattern 5 length
-        * bit 15:8 pattern 6 length
-        * bit 7:0 pattern 7 length
+        * Disassociate pattern
+        * --------------------
+        * Frame control = 00 00 1010
+        * DA, SA, BSSID = x:x:x:x:x:x
+        * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
+        *                          | x:x:x:x:x:x  -- 22 bytes
         *
-        * the below logic writes out the new
-        * pattern length for the corresponding
-        * pattern_count, while masking out the
-        * other fields
+        * Deauthenticate pattern
+        * ----------------------
+        * Frame control = 00 00 1100
+        * DA, SA, BSSID = x:x:x:x:x:x
+        * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
+        *                          | x:x:x:x:x:x  -- 22 bytes
         */
 
-       ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
-
-       if (pattern_count < 4) {
-               /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
-               set = (pattern_len & AR_WOW_LENGTH_MAX) <<
-                      AR_WOW_LEN1_SHIFT(pattern_count);
-               clr = AR_WOW_LENGTH1_MASK(pattern_count);
-               REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
-       } else {
-               /* Pattern 4-7 uses AR_WOW_LENGTH2 register */
-               set = (pattern_len & AR_WOW_LENGTH_MAX) <<
-                      AR_WOW_LEN2_SHIFT(pattern_count);
-               clr = AR_WOW_LENGTH2_MASK(pattern_count);
-               REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
-       }
+       /* Create Disassociate Pattern first */
 
-}
-EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
+       byte_cnt = 0;
 
-u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
-{
-       u32 wow_status = 0;
-       u32 val = 0, rval;
+       /* Fill out the mask with all FF's */
 
-       /*
-        * read the WoW status register to know
-        * the wakeup reason
-        */
-       rval = REG_READ(ah, AR_WOW_PATTERN);
-       val = AR_WOW_STATUS(rval);
+       for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
+               dis_deauth_mask[i] = 0xff;
 
-       /*
-        * mask only the WoW events that we have enabled. Sometimes
-        * we have spurious WoW events from the AR_WOW_PATTERN
-        * register. This mask will clean it up.
-        */
+       /* copy the first byte of frame control field */
+       dis_deauth_pattern[byte_cnt] = 0xa0;
+       byte_cnt++;
 
-       val &= ah->wow_event_mask;
-
-       if (val) {
-               if (val & AR_WOW_MAGIC_PAT_FOUND)
-                       wow_status |= AH_WOW_MAGIC_PATTERN_EN;
-               if (AR_WOW_PATTERN_FOUND(val))
-                       wow_status |= AH_WOW_USER_PATTERN_EN;
-               if (val & AR_WOW_KEEP_ALIVE_FAIL)
-                       wow_status |= AH_WOW_LINK_CHANGE;
-               if (val & AR_WOW_BEACON_FAIL)
-                       wow_status |= AH_WOW_BEACON_MISS;
-       }
+       /* skip 2nd byte of frame control and Duration field */
+       byte_cnt += 3;
 
        /*
-        * set and clear WOW_PME_CLEAR registers for the chip to
-        * generate next wow signal.
-        * disable D3 before accessing other registers ?
+        * need not match the destination mac address, it can be a broadcast
+        * mac address or an unicast to this station
         */
+       byte_cnt += 6;
 
-       /* do we need to check the bit value 0x01000000 (7-10) ?? */
-       REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR,
-               AR_PMCTRL_PWR_STATE_D1D3);
+       /* copy the source mac address */
+       memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
 
-       /*
-        * clear all events
-        */
-       REG_WRITE(ah, AR_WOW_PATTERN,
-                 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
+       byte_cnt += 6;
 
-       /*
-        * restore the beacon threshold to init value
-        */
-       REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
+       /* copy the bssid, its same as the source mac address */
+
+       memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
+
+       /* Create Disassociate pattern mask */
+
+       dis_deauth_mask[0] = 0xfe;
+       dis_deauth_mask[1] = 0x03;
+       dis_deauth_mask[2] = 0xc0;
+
+       ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
 
+       ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
+                                  pattern_count, byte_cnt);
+
+       pattern_count++;
        /*
-        * Restore the way the PCI-E reset, Power-On-Reset, external
-        * PCIE_POR_SHORT pins are tied to its original value.
-        * Previously just before WoW sleep, we untie the PCI-E
-        * reset to our Chip's Power On Reset so that any PCI-E
-        * reset from the bus will not reset our chip
+        * for de-authenticate pattern, only the first byte of the frame
+        * control field gets changed from 0xA0 to 0xC0
         */
-       if (ah->is_pciexpress)
-               ath9k_hw_configpcipowersave(ah, false);
+       dis_deauth_pattern[0] = 0xC0;
 
-       ah->wow_event_mask = 0;
+       ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
+                                  pattern_count, byte_cnt);
 
-       return wow_status;
 }
-EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
 
-void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
+static void ath9k_wow_add_pattern(struct ath_softc *sc,
+                                 struct cfg80211_wowlan *wowlan)
 {
-       u32 wow_event_mask;
-       u32 set, clr;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath9k_wow_pattern *wow_pattern = NULL;
+       struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
+       int mask_len;
+       s8 i = 0;
 
-       /*
-        * wow_event_mask is a mask to the AR_WOW_PATTERN register to
-        * indicate which WoW events we have enabled. The WoW events
-        * are from the 'pattern_enable' in this function and
-        * 'pattern_count' of ath9k_hw_wow_apply_pattern()
-        */
-       wow_event_mask = ah->wow_event_mask;
+       if (!wowlan->n_patterns)
+               return;
 
        /*
-        * Untie Power-on-Reset from the PCI-E-Reset. When we are in
-        * WOW sleep, we do want the Reset from the PCI-E to disturb
-        * our hw state
+        * Add the new user configured patterns
         */
-       if (ah->is_pciexpress) {
+       for (i = 0; i < wowlan->n_patterns; i++) {
+
+               wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
+
+               if (!wow_pattern)
+                       return;
+
+               /*
+                * TODO: convert the generic user space pattern to
+                * appropriate chip specific/802.11 pattern.
+                */
+
+               mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
+               memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
+               memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
+               memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
+                      patterns[i].pattern_len);
+               memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
+               wow_pattern->pattern_len = patterns[i].pattern_len;
+
                /*
-                * we need to untie the internal POR (power-on-reset)
-                * to the external PCI-E reset. We also need to tie
-                * the PCI-E Phy reset to the PCI-E reset.
+                * just need to take care of deauth and disssoc pattern,
+                * make sure we don't overwrite them.
                 */
-               set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
-               clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
-               REG_RMW(ah, AR_WA, set, clr);
+
+               ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
+                                          wow_pattern->mask_bytes,
+                                          i + 2,
+                                          wow_pattern->pattern_len);
+               kfree(wow_pattern);
+
        }
 
-       /*
-        * set the power states appropriately and enable PME
-        */
-       set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
-             AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
+}
 
-       /*
-        * set and clear WOW_PME_CLEAR registers for the chip
-        * to generate next wow signal.
-        */
-       REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
-       clr = AR_PMCTRL_WOW_PME_CLR;
-       REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
+int ath9k_suspend(struct ieee80211_hw *hw,
+                 struct cfg80211_wowlan *wowlan)
+{
+       struct ath_softc *sc = hw->priv;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 wow_triggers_enabled = 0;
+       int ret = 0;
 
-       /*
-        * Setup for:
-        *      - beacon misses
-        *      - magic pattern
-        *      - keep alive timeout
-        *      - pattern matching
-        */
+       mutex_lock(&sc->mutex);
 
-       /*
-        * Program default values for pattern backoff, aifs/slot/KAL count,
-        * beacon miss timeout, KAL timeout, etc.
-        */
-       set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
-       REG_SET_BIT(ah, AR_WOW_PATTERN, set);
+       ath_cancel_work(sc);
+       ath_stop_ani(sc);
+       del_timer_sync(&sc->rx_poll_timer);
 
-       set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
-             AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
-             AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT);
-       REG_SET_BIT(ah, AR_WOW_COUNT, set);
+       if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
+               ath_dbg(common, ANY, "Device not present\n");
+               ret = -EINVAL;
+               goto fail_wow;
+       }
 
-       if (pattern_enable & AH_WOW_BEACON_MISS)
-               set = AR_WOW_BEACON_TIMO;
-       /* We are not using beacon miss, program a large value */
-       else
-               set = AR_WOW_BEACON_TIMO_MAX;
+       if (WARN_ON(!wowlan)) {
+               ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
+               ret = -EINVAL;
+               goto fail_wow;
+       }
 
-       REG_WRITE(ah, AR_WOW_BCN_TIMO, set);
+       if (!device_can_wakeup(sc->dev)) {
+               ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
+               ret = 1;
+               goto fail_wow;
+       }
 
        /*
-        * Keep alive timo in ms except AR9280
+        * none of the sta vifs are associated
+        * and we are not currently handling multivif
+        * cases, for instance we have to seperately
+        * configure 'keep alive frame' for each
+        * STA.
         */
-       if (!pattern_enable)
-               set = AR_WOW_KEEP_ALIVE_NEVER;
-       else
-               set = KAL_TIMEOUT * 32;
 
-       REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set);
+       if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
+               ath_dbg(common, WOW, "None of the STA vifs are associated\n");
+               ret = 1;
+               goto fail_wow;
+       }
+
+       if (sc->nvifs > 1) {
+               ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
+               ret = 1;
+               goto fail_wow;
+       }
+
+       ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
+
+       ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
+               wow_triggers_enabled);
+
+       ath9k_ps_wakeup(sc);
+
+       ath9k_stop_btcoex(sc);
 
        /*
-        * Keep alive delay in us. based on 'power on clock',
-        * therefore in usec
+        * Enable wake up on recieving disassoc/deauth
+        * frame by default.
         */
-       set = KAL_DELAY * 1000;
-       REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set);
+       ath9k_wow_add_disassoc_deauth_pattern(sc);
+
+       if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
+               ath9k_wow_add_pattern(sc, wowlan);
 
+       spin_lock_bh(&sc->sc_pcu_lock);
        /*
-        * Create keep alive pattern to respond to beacons
+        * To avoid false wake, we enable beacon miss interrupt only
+        * when we go to sleep. We save the current interrupt mask
+        * so we can restore it after the system wakes up
         */
-       ath9k_wow_create_keep_alive_pattern(ah);
+       sc->wow_intr_before_sleep = ah->imask;
+       ah->imask &= ~ATH9K_INT_GLOBAL;
+       ath9k_hw_disable_interrupts(ah);
+       ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
+       ath9k_hw_set_interrupts(ah);
+       ath9k_hw_enable_interrupts(ah);
+
+       spin_unlock_bh(&sc->sc_pcu_lock);
 
        /*
-        * Configure MAC WoW Registers
+        * we can now sync irq and kill any running tasklets, since we already
+        * disabled interrupts and not holding a spin lock
         */
-       set = 0;
-       /* Send keep alive timeouts anyway */
-       clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
+       synchronize_irq(sc->irq);
+       tasklet_kill(&sc->intr_tq);
 
-       if (pattern_enable & AH_WOW_LINK_CHANGE)
-               wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
-       else
-               set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
+       ath9k_hw_wow_enable(ah, wow_triggers_enabled);
 
-       set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
-       REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
+       ath9k_ps_restore(sc);
+       ath_dbg(common, ANY, "WoW enabled in ath9k\n");
+       atomic_inc(&sc->wow_sleep_proc_intr);
 
-       /*
-        * we are relying on a bmiss failure. ensure we have
-        * enough threshold to prevent false positives
-        */
-       REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR,
-                     AR_WOW_BMISSTHRESHOLD);
+fail_wow:
+       mutex_unlock(&sc->mutex);
+       return ret;
+}
+
+int ath9k_resume(struct ieee80211_hw *hw)
+{
+       struct ath_softc *sc = hw->priv;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 wow_status;
 
-       set = 0;
-       clr = 0;
+       mutex_lock(&sc->mutex);
 
-       if (pattern_enable & AH_WOW_BEACON_MISS) {
-               set = AR_WOW_BEACON_FAIL_EN;
-               wow_event_mask |= AR_WOW_BEACON_FAIL;
-       } else {
-               clr = AR_WOW_BEACON_FAIL_EN;
+       ath9k_ps_wakeup(sc);
+
+       spin_lock_bh(&sc->sc_pcu_lock);
+
+       ath9k_hw_disable_interrupts(ah);
+       ah->imask = sc->wow_intr_before_sleep;
+       ath9k_hw_set_interrupts(ah);
+       ath9k_hw_enable_interrupts(ah);
+
+       spin_unlock_bh(&sc->sc_pcu_lock);
+
+       wow_status = ath9k_hw_wow_wakeup(ah);
+
+       if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
+               /*
+                * some devices may not pick beacon miss
+                * as the reason they woke up so we add
+                * that here for that shortcoming.
+                */
+               wow_status |= AH_WOW_BEACON_MISS;
+               atomic_dec(&sc->wow_got_bmiss_intr);
+               ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
        }
 
-       REG_RMW(ah, AR_WOW_BCN_EN, set, clr);
+       atomic_dec(&sc->wow_sleep_proc_intr);
 
-       set = 0;
-       clr = 0;
-       /*
-        * Enable the magic packet registers
-        */
-       if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
-               set = AR_WOW_MAGIC_EN;
-               wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
-       } else {
-               clr = AR_WOW_MAGIC_EN;
+       if (wow_status) {
+               ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
+                       ath9k_hw_wow_event_to_string(wow_status), wow_status);
        }
-       set |= AR_WOW_MAC_INTR_EN;
-       REG_RMW(ah, AR_WOW_PATTERN, set, clr);
 
-       REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
-                 AR_WOW_PATTERN_SUPPORTED);
+       ath_restart_work(sc);
+       ath9k_start_btcoex(sc);
 
-       /*
-        * Set the power states appropriately and enable PME
-        */
-       clr = 0;
-       set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
-             AR_PMCTRL_PWR_PM_CTRL_ENA;
+       ath9k_ps_restore(sc);
+       mutex_unlock(&sc->mutex);
 
-       clr = AR_PCIE_PM_CTRL_ENA;
-       REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
+       return 0;
+}
 
-       /*
-        * this is needed to prevent the chip waking up
-        * the host within 3-4 seconds with certain
-        * platform/BIOS. The fix is to enable
-        * D1 & D3 to match original definition and
-        * also match the OTP value. Anyway this
-        * is more related to SW WOW.
-        */
-       clr = AR_PMCTRL_PWR_STATE_D1D3;
-       REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
+void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
+{
+       struct ath_softc *sc = hw->priv;
 
-       set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
-       REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
+       mutex_lock(&sc->mutex);
+       device_init_wakeup(sc->dev, 1);
+       device_set_wakeup_enable(sc->dev, enabled);
+       mutex_unlock(&sc->mutex);
+}
 
-       REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
+void ath9k_init_wow(struct ieee80211_hw *hw)
+{
+       struct ath_softc *sc = hw->priv;
 
-       /* to bring down WOW power low margin */
-       set = BIT(13);
-       REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
-       /* HW WoW */
-       clr = BIT(5);
-       REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
+       if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
+           (sc->driver_data & ATH9K_PCI_WOW) &&
+           device_can_wakeup(sc->dev))
+               hw->wiphy->wowlan = &ath9k_wowlan_support;
 
-       ath9k_hw_set_powermode_wow_sleep(ah);
-       ah->wow_event_mask = wow_event_mask;
+       atomic_set(&sc->wow_sleep_proc_intr, -1);
+       atomic_set(&sc->wow_got_bmiss_intr, -1);
 }
-EXPORT_SYMBOL(ath9k_hw_wow_enable);
index 09cdbcd097394a3a2c324230c2743f5d181b0900..24846d91554b98f56fb07caed59a4ccfb5ff8684 100644 (file)
@@ -1786,6 +1786,9 @@ bool ath_drain_all_txq(struct ath_softc *sc)
                if (!ATH_TXQ_SETUP(sc, i))
                        continue;
 
+               if (!sc->tx.txq[i].axq_depth)
+                       continue;
+
                if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum))
                        npend |= BIT(i);
        }
@@ -2749,6 +2752,8 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
        }
 }
 
+#ifdef CONFIG_ATH9K_TX99
+
 int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
                    struct ath_tx_control *txctl)
 {
@@ -2791,3 +2796,5 @@ int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
 
        return 0;
 }
+
+#endif /* CONFIG_ATH9K_TX99 */
index 1217c52ab28e6b07847217890bb6f1d9840a84b1..9e154732afaacfefe661befa0053e881ba083106 100644 (file)
@@ -37,17 +37,18 @@ static int __ath_regd_init(struct ath_regulatory *reg);
 
 /* We enable active scan on these a case by case basis by regulatory domain */
 #define ATH9K_2GHZ_CH12_13     REG_RULE(2467-10, 2472+10, 40, 0, 20,\
-                                       NL80211_RRF_PASSIVE_SCAN)
+                                        NL80211_RRF_NO_IR)
 #define ATH9K_2GHZ_CH14                REG_RULE(2484-10, 2484+10, 40, 0, 20,\
-                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
+                                        NL80211_RRF_NO_IR | \
+                                        NL80211_RRF_NO_OFDM)
 
 /* We allow IBSS on these on a case by case basis by regulatory domain */
 #define ATH9K_5GHZ_5150_5350   REG_RULE(5150-10, 5350+10, 80, 0, 30,\
-                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+                                        NL80211_RRF_NO_IR)
 #define ATH9K_5GHZ_5470_5850   REG_RULE(5470-10, 5850+10, 80, 0, 30,\
-                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+                                        NL80211_RRF_NO_IR)
 #define ATH9K_5GHZ_5725_5850   REG_RULE(5725-10, 5850+10, 80, 0, 30,\
-                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+                                        NL80211_RRF_NO_IR)
 
 #define ATH9K_2GHZ_ALL         ATH9K_2GHZ_CH01_11, \
                                ATH9K_2GHZ_CH12_13, \
@@ -113,6 +114,87 @@ static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
        }
 };
 
+static bool dynamic_country_user_possible(struct ath_regulatory *reg)
+{
+       if (config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
+               return true;
+
+       switch (reg->country_code) {
+       case CTRY_UNITED_STATES:
+       case CTRY_JAPAN1:
+       case CTRY_JAPAN2:
+       case CTRY_JAPAN3:
+       case CTRY_JAPAN4:
+       case CTRY_JAPAN5:
+       case CTRY_JAPAN6:
+       case CTRY_JAPAN7:
+       case CTRY_JAPAN8:
+       case CTRY_JAPAN9:
+       case CTRY_JAPAN10:
+       case CTRY_JAPAN11:
+       case CTRY_JAPAN12:
+       case CTRY_JAPAN13:
+       case CTRY_JAPAN14:
+       case CTRY_JAPAN15:
+       case CTRY_JAPAN16:
+       case CTRY_JAPAN17:
+       case CTRY_JAPAN18:
+       case CTRY_JAPAN19:
+       case CTRY_JAPAN20:
+       case CTRY_JAPAN21:
+       case CTRY_JAPAN22:
+       case CTRY_JAPAN23:
+       case CTRY_JAPAN24:
+       case CTRY_JAPAN25:
+       case CTRY_JAPAN26:
+       case CTRY_JAPAN27:
+       case CTRY_JAPAN28:
+       case CTRY_JAPAN29:
+       case CTRY_JAPAN30:
+       case CTRY_JAPAN31:
+       case CTRY_JAPAN32:
+       case CTRY_JAPAN33:
+       case CTRY_JAPAN34:
+       case CTRY_JAPAN35:
+       case CTRY_JAPAN36:
+       case CTRY_JAPAN37:
+       case CTRY_JAPAN38:
+       case CTRY_JAPAN39:
+       case CTRY_JAPAN40:
+       case CTRY_JAPAN41:
+       case CTRY_JAPAN42:
+       case CTRY_JAPAN43:
+       case CTRY_JAPAN44:
+       case CTRY_JAPAN45:
+       case CTRY_JAPAN46:
+       case CTRY_JAPAN47:
+       case CTRY_JAPAN48:
+       case CTRY_JAPAN49:
+       case CTRY_JAPAN50:
+       case CTRY_JAPAN51:
+       case CTRY_JAPAN52:
+       case CTRY_JAPAN53:
+       case CTRY_JAPAN54:
+       case CTRY_JAPAN55:
+       case CTRY_JAPAN56:
+       case CTRY_JAPAN57:
+       case CTRY_JAPAN58:
+       case CTRY_JAPAN59:
+               return false;
+       }
+
+       return true;
+}
+
+static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg)
+{
+       if (!config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS))
+               return false;
+       if (!dynamic_country_user_possible(reg))
+               return false;
+       return true;
+}
+
 static inline bool is_wwr_sku(u16 regd)
 {
        return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
@@ -177,118 +259,139 @@ static bool ath_is_radar_freq(u16 center_freq)
        return (center_freq >= 5260 && center_freq <= 5700);
 }
 
+static void ath_force_clear_no_ir_chan(struct wiphy *wiphy,
+                                      struct ieee80211_channel *ch)
+{
+       const struct ieee80211_reg_rule *reg_rule;
+
+       reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
+       if (IS_ERR(reg_rule))
+               return;
+
+       if (!(reg_rule->flags & NL80211_RRF_NO_IR))
+               if (ch->flags & IEEE80211_CHAN_NO_IR)
+                       ch->flags &= ~IEEE80211_CHAN_NO_IR;
+}
+
+static void ath_force_clear_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
+{
+       struct ieee80211_channel *ch;
+
+       ch = ieee80211_get_channel(wiphy, center_freq);
+       if (!ch)
+               return;
+
+       ath_force_clear_no_ir_chan(wiphy, ch);
+}
+
+static void ath_force_no_ir_chan(struct ieee80211_channel *ch)
+{
+       ch->flags |= IEEE80211_CHAN_NO_IR;
+}
+
+static void ath_force_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
+{
+       struct ieee80211_channel *ch;
+
+       ch = ieee80211_get_channel(wiphy, center_freq);
+       if (!ch)
+               return;
+
+       ath_force_no_ir_chan(ch);
+}
+
+static void
+__ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
+                               struct ath_regulatory *reg,
+                               enum nl80211_reg_initiator initiator,
+                               struct ieee80211_channel *ch)
+{
+       if (ath_is_radar_freq(ch->center_freq) ||
+           (ch->flags & IEEE80211_CHAN_RADAR))
+               return;
+
+       switch (initiator) {
+       case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+               ath_force_clear_no_ir_chan(wiphy, ch);
+               break;
+       case NL80211_REGDOM_SET_BY_USER:
+               if (ath_reg_dyn_country_user_allow(reg))
+                       ath_force_clear_no_ir_chan(wiphy, ch);
+               break;
+       default:
+               if (ch->beacon_found)
+                       ch->flags &= ~IEEE80211_CHAN_NO_IR;
+       }
+}
+
 /*
- * N.B: These exception rules do not apply radar freqs.
+ * These exception rules do not apply radar frequencies.
  *
- * - We enable adhoc (or beaconing) if allowed by 11d
- * - We enable active scan if the channel is allowed by 11d
+ * - We enable initiating radiation if the country IE says its fine:
  * - If no country IE has been processed and a we determine we have
- *   received a beacon on a channel we can enable active scan and
- *   adhoc (or beaconing).
+ *   received a beacon on a channel we can enable initiating radiation.
  */
 static void
 ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
+                             struct ath_regulatory *reg,
                              enum nl80211_reg_initiator initiator)
 {
        enum ieee80211_band band;
        struct ieee80211_supported_band *sband;
-       const struct ieee80211_reg_rule *reg_rule;
        struct ieee80211_channel *ch;
        unsigned int i;
 
        for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
-
                if (!wiphy->bands[band])
                        continue;
-
                sband = wiphy->bands[band];
-
                for (i = 0; i < sband->n_channels; i++) {
-
                        ch = &sband->channels[i];
-
-                       if (ath_is_radar_freq(ch->center_freq) ||
-                           (ch->flags & IEEE80211_CHAN_RADAR))
-                               continue;
-
-                       if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
-                               reg_rule = freq_reg_info(wiphy, ch->center_freq);
-                               if (IS_ERR(reg_rule))
-                                       continue;
-                               /*
-                                * If 11d had a rule for this channel ensure
-                                * we enable adhoc/beaconing if it allows us to
-                                * use it. Note that we would have disabled it
-                                * by applying our static world regdomain by
-                                * default during init, prior to calling our
-                                * regulatory_hint().
-                                */
-                               if (!(reg_rule->flags &
-                                   NL80211_RRF_NO_IBSS))
-                                       ch->flags &=
-                                         ~IEEE80211_CHAN_NO_IBSS;
-                               if (!(reg_rule->flags &
-                                   NL80211_RRF_PASSIVE_SCAN))
-                                       ch->flags &=
-                                         ~IEEE80211_CHAN_PASSIVE_SCAN;
-                       } else {
-                               if (ch->beacon_found)
-                                       ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
-                                         IEEE80211_CHAN_PASSIVE_SCAN);
-                       }
+                       __ath_reg_apply_beaconing_flags(wiphy, reg,
+                                                       initiator, ch);
                }
        }
-
 }
 
-/* Allows active scan scan on Ch 12 and 13 */
+/**
+ * ath_reg_apply_ir_flags()
+ * @wiphy: the wiphy to use
+ * @initiator: the regulatory hint initiator
+ *
+ * If no country IE has been received always enable passive scan
+ * and no-ibss on these channels. This is only done for specific
+ * regulatory SKUs.
+ *
+ * If a country IE has been received check its rule for this
+ * channel first before enabling active scan. The passive scan
+ * would have been enforced by the initial processing of our
+ * custom regulatory domain.
+ */
 static void
-ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
-                               enum nl80211_reg_initiator initiator)
+ath_reg_apply_ir_flags(struct wiphy *wiphy,
+                      struct ath_regulatory *reg,
+                      enum nl80211_reg_initiator initiator)
 {
        struct ieee80211_supported_band *sband;
-       struct ieee80211_channel *ch;
-       const struct ieee80211_reg_rule *reg_rule;
 
        sband = wiphy->bands[IEEE80211_BAND_2GHZ];
        if (!sband)
                return;
 
-       /*
-        * If no country IE has been received always enable active scan
-        * on these channels. This is only done for specific regulatory SKUs
-        */
-       if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
-               ch = &sband->channels[11]; /* CH 12 */
-               if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                       ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-               ch = &sband->channels[12]; /* CH 13 */
-               if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                       ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-               return;
-       }
-
-       /*
-        * If a country IE has been received check its rule for this
-        * channel first before enabling active scan. The passive scan
-        * would have been enforced by the initial processing of our
-        * custom regulatory domain.
-        */
-
-       ch = &sband->channels[11]; /* CH 12 */
-       reg_rule = freq_reg_info(wiphy, ch->center_freq);
-       if (!IS_ERR(reg_rule)) {
-               if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
-                       if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                               ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-       }
-
-       ch = &sband->channels[12]; /* CH 13 */
-       reg_rule = freq_reg_info(wiphy, ch->center_freq);
-       if (!IS_ERR(reg_rule)) {
-               if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
-                       if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                               ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+       switch(initiator) {
+       case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+               ath_force_clear_no_ir_freq(wiphy, 2467);
+               ath_force_clear_no_ir_freq(wiphy, 2472);
+               break;
+       case NL80211_REGDOM_SET_BY_USER:
+               if (!ath_reg_dyn_country_user_allow(reg))
+                       break;
+               ath_force_clear_no_ir_freq(wiphy, 2467);
+               ath_force_clear_no_ir_freq(wiphy, 2472);
+               break;
+       default:
+               ath_force_no_ir_freq(wiphy, 2467);
+               ath_force_no_ir_freq(wiphy, 2472);
        }
 }
 
@@ -320,8 +423,7 @@ static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
                 */
                if (!(ch->flags & IEEE80211_CHAN_DISABLED))
                        ch->flags |= IEEE80211_CHAN_RADAR |
-                                    IEEE80211_CHAN_NO_IBSS |
-                                    IEEE80211_CHAN_PASSIVE_SCAN;
+                                    IEEE80211_CHAN_NO_IR;
        }
 }
 
@@ -335,12 +437,15 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy,
        case 0x66:
        case 0x67:
        case 0x6C:
-               ath_reg_apply_beaconing_flags(wiphy, initiator);
+               ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
                break;
        case 0x68:
-               ath_reg_apply_beaconing_flags(wiphy, initiator);
-               ath_reg_apply_active_scan_flags(wiphy, initiator);
+               ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
+               ath_reg_apply_ir_flags(wiphy, reg, initiator);
                break;
+       default:
+               if (ath_reg_dyn_country_user_allow(reg))
+                       ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
        }
 }
 
@@ -393,89 +498,6 @@ static void ath_reg_dyn_country(struct wiphy *wiphy,
               reg_initiator_name(request->initiator));
 }
 
-static bool dynamic_country_user_possible(struct ath_regulatory *reg)
-{
-       if (config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
-               return true;
-
-       switch (reg->country_code) {
-       case CTRY_UNITED_STATES:
-       case CTRY_JAPAN1:
-       case CTRY_JAPAN2:
-       case CTRY_JAPAN3:
-       case CTRY_JAPAN4:
-       case CTRY_JAPAN5:
-       case CTRY_JAPAN6:
-       case CTRY_JAPAN7:
-       case CTRY_JAPAN8:
-       case CTRY_JAPAN9:
-       case CTRY_JAPAN10:
-       case CTRY_JAPAN11:
-       case CTRY_JAPAN12:
-       case CTRY_JAPAN13:
-       case CTRY_JAPAN14:
-       case CTRY_JAPAN15:
-       case CTRY_JAPAN16:
-       case CTRY_JAPAN17:
-       case CTRY_JAPAN18:
-       case CTRY_JAPAN19:
-       case CTRY_JAPAN20:
-       case CTRY_JAPAN21:
-       case CTRY_JAPAN22:
-       case CTRY_JAPAN23:
-       case CTRY_JAPAN24:
-       case CTRY_JAPAN25:
-       case CTRY_JAPAN26:
-       case CTRY_JAPAN27:
-       case CTRY_JAPAN28:
-       case CTRY_JAPAN29:
-       case CTRY_JAPAN30:
-       case CTRY_JAPAN31:
-       case CTRY_JAPAN32:
-       case CTRY_JAPAN33:
-       case CTRY_JAPAN34:
-       case CTRY_JAPAN35:
-       case CTRY_JAPAN36:
-       case CTRY_JAPAN37:
-       case CTRY_JAPAN38:
-       case CTRY_JAPAN39:
-       case CTRY_JAPAN40:
-       case CTRY_JAPAN41:
-       case CTRY_JAPAN42:
-       case CTRY_JAPAN43:
-       case CTRY_JAPAN44:
-       case CTRY_JAPAN45:
-       case CTRY_JAPAN46:
-       case CTRY_JAPAN47:
-       case CTRY_JAPAN48:
-       case CTRY_JAPAN49:
-       case CTRY_JAPAN50:
-       case CTRY_JAPAN51:
-       case CTRY_JAPAN52:
-       case CTRY_JAPAN53:
-       case CTRY_JAPAN54:
-       case CTRY_JAPAN55:
-       case CTRY_JAPAN56:
-       case CTRY_JAPAN57:
-       case CTRY_JAPAN58:
-       case CTRY_JAPAN59:
-               return false;
-       }
-
-       return true;
-}
-
-static void ath_reg_dyn_country_user(struct wiphy *wiphy,
-                                    struct ath_regulatory *reg,
-                                    struct regulatory_request *request)
-{
-       if (!config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS))
-               return;
-       if (!dynamic_country_user_possible(reg))
-               return;
-       ath_reg_dyn_country(wiphy, reg, request);
-}
-
 void ath_reg_notifier_apply(struct wiphy *wiphy,
                            struct regulatory_request *request,
                            struct ath_regulatory *reg)
@@ -508,7 +530,8 @@ void ath_reg_notifier_apply(struct wiphy *wiphy,
        case NL80211_REGDOM_SET_BY_DRIVER:
                break;
        case NL80211_REGDOM_SET_BY_USER:
-               ath_reg_dyn_country_user(wiphy, reg, request);
+               if (ath_reg_dyn_country_user_allow(reg))
+                       ath_reg_dyn_country(wiphy, reg, request);
                break;
        case NL80211_REGDOM_SET_BY_COUNTRY_IE:
                ath_reg_dyn_country(wiphy, reg, request);
@@ -609,7 +632,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
        const struct ieee80211_regdomain *regd;
 
        wiphy->reg_notifier = reg_notifier;
-       wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
+       wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
 
        if (ath_is_world_regd(reg)) {
                /*
@@ -617,7 +640,8 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
                 * saved on the wiphy orig_* parameters
                 */
                regd = ath_world_regdomain(reg);
-               wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+               wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
+                                          REGULATORY_COUNTRY_IE_FOLLOW_POWER;
        } else {
                /*
                 * This gets applied in the case of the absence of CRDA,
index c02dbc618724720cee3c97a3fa86a249188fff5b..3c2ef0c32f72c7ef37b9b032e3b66ec3ab9619d6 100644 (file)
@@ -2644,7 +2644,7 @@ struct wcn36xx_hal_trigger_ba_rsp_candidate {
        struct add_ba_info ba_info[STACFG_MAX_TC];
 } __packed;
 
-struct wcn36xx_hal_trigget_ba_req_candidate {
+struct wcn36xx_hal_trigger_ba_req_candidate {
        u8 sta_index;
        u8 tid_bitmap;
 } __packed;
index 7839b31e4826e5013a391b94f405483f6c4e977f..e64a6784079e20446ad57078f607e0f01b7565a1 100644 (file)
@@ -641,7 +641,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
                dev_kfree_skb(skb);
        }
 
-       if (changed & BSS_CHANGED_BEACON_ENABLED) {
+       if (changed & BSS_CHANGED_BEACON_ENABLED ||
+           changed & BSS_CHANGED_BEACON) {
                wcn36xx_dbg(WCN36XX_DBG_MAC,
                            "mac bss changed beacon enabled %d\n",
                            bss_conf->enable_beacon);
index 366339421d4f1c924e4e1e69c34ce88bce9ab028..823631cdb872bc8799229a9d91388d377a5511fc 100644 (file)
@@ -115,6 +115,22 @@ static void wcn36xx_smd_set_sta_ht_params(struct ieee80211_sta *sta,
        }
 }
 
+static void wcn36xx_smd_set_sta_default_ht_params(
+               struct wcn36xx_hal_config_sta_params *sta_params)
+{
+       sta_params->ht_capable = 1;
+       sta_params->tx_channel_width_set = 1;
+       sta_params->lsig_txop_protection = 1;
+       sta_params->max_ampdu_size = 3;
+       sta_params->max_ampdu_density = 5;
+       sta_params->max_amsdu_size = 0;
+       sta_params->sgi_20Mhz = 1;
+       sta_params->sgi_40mhz = 1;
+       sta_params->green_field_capable = 1;
+       sta_params->delayed_ba_support = 0;
+       sta_params->dsss_cck_mode_40mhz = 1;
+}
+
 static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn,
                struct ieee80211_vif *vif,
                struct ieee80211_sta *sta,
@@ -172,6 +188,7 @@ static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn,
                        sizeof(priv_sta->supported_rates));
        } else {
                wcn36xx_set_default_rates(&sta_params->supported_rates);
+               wcn36xx_smd_set_sta_default_ht_params(sta_params);
        }
 }
 
@@ -1838,7 +1855,7 @@ out:
 int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index)
 {
        struct wcn36xx_hal_trigger_ba_req_msg msg_body;
-       struct wcn36xx_hal_trigget_ba_req_candidate *candidate;
+       struct wcn36xx_hal_trigger_ba_req_candidate *candidate;
        int ret = 0;
 
        mutex_lock(&wcn->hal_mutex);
@@ -1849,7 +1866,7 @@ int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index)
        msg_body.header.len += sizeof(*candidate);
        PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
 
-       candidate = (struct wcn36xx_hal_trigget_ba_req_candidate *)
+       candidate = (struct wcn36xx_hal_trigger_ba_req_candidate *)
                (wcn->hal_buf + sizeof(msg_body));
        candidate->sta_index = sta_index;
        candidate->tid_bitmap = 1;
index 58b63833e8e72d1d8dee64b31c14374369ecb072..8fa5cbace5abba1e027954a64b312bdc37f7b13c 100644 (file)
@@ -54,7 +54,7 @@ enum wcn36xx_debug_mask {
 };
 
 #define wcn36xx_err(fmt, arg...)                               \
-       printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg);
+       printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg)
 
 #define wcn36xx_warn(fmt, arg...)                              \
        printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg)
index 54e36fcb39542e8361dfdc019134f3ba1538de8f..fcfed6b99a62d6e16e66634df2df85198cbb64da 100644 (file)
@@ -4,13 +4,12 @@ config BRCMUTIL
 config BRCMSMAC
        tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
        depends on MAC80211
-       depends on BCMA
+       depends on BCMA_POSSIBLE
+       select BCMA
        select NEW_LEDS if BCMA_DRIVER_GPIO
        select LEDS_CLASS if BCMA_DRIVER_GPIO
        select BRCMUTIL
        select FW_LOADER
-       select CRC_CCITT
-       select CRC8
        select CORDIC
        ---help---
          This module adds support for PCIe wireless adapters based on Broadcom
index 8e9b1221b32c1918f7981cf2d4228b44684ac091..2082402d4b6364e03424f4ef00161b0fae9c298b 100644 (file)
@@ -28,7 +28,8 @@ brcmfmac-objs += \
                fweh.o \
                fwsignal.o \
                p2p.o \
-               dhd_cdc.o \
+               proto.o \
+               bcdc.o \
                dhd_common.o \
                dhd_linux.o \
                btcoex.o
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
new file mode 100644 (file)
index 0000000..06848e4
--- /dev/null
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+/*******************************************************************************
+ * Communicates with the dongle by using dcmd codes.
+ * For certain dcmd codes, the dongle interprets string data from the host.
+ ******************************************************************************/
+
+#include <linux/types.h>
+#include <linux/netdevice.h>
+
+#include <brcmu_utils.h>
+#include <brcmu_wifi.h>
+
+#include "dhd.h"
+#include "dhd_bus.h"
+#include "fwsignal.h"
+#include "dhd_dbg.h"
+#include "tracepoint.h"
+#include "proto.h"
+#include "bcdc.h"
+
+struct brcmf_proto_bcdc_dcmd {
+       __le32 cmd;     /* dongle command value */
+       __le32 len;     /* lower 16: output buflen;
+                        * upper 16: input buflen (excludes header) */
+       __le32 flags;   /* flag defns given below */
+       __le32 status;  /* status code returned from the device */
+};
+
+/* Max valid buffer size that can be sent to the dongle */
+#define BCDC_MAX_MSG_SIZE      (ETH_FRAME_LEN+ETH_FCS_LEN)
+
+/* BCDC flag definitions */
+#define BCDC_DCMD_ERROR                0x01            /* 1=cmd failed */
+#define BCDC_DCMD_SET          0x02            /* 0=get, 1=set cmd */
+#define BCDC_DCMD_IF_MASK      0xF000          /* I/F index */
+#define BCDC_DCMD_IF_SHIFT     12
+#define BCDC_DCMD_ID_MASK      0xFFFF0000      /* id an cmd pairing */
+#define BCDC_DCMD_ID_SHIFT     16              /* ID Mask shift bits */
+#define BCDC_DCMD_ID(flags)    \
+       (((flags) & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT)
+
+/*
+ * BCDC header - Broadcom specific extension of CDC.
+ * Used on data packets to convey priority across USB.
+ */
+#define        BCDC_HEADER_LEN         4
+#define BCDC_PROTO_VER         2       /* Protocol version */
+#define BCDC_FLAG_VER_MASK     0xf0    /* Protocol version mask */
+#define BCDC_FLAG_VER_SHIFT    4       /* Protocol version shift */
+#define BCDC_FLAG_SUM_GOOD     0x04    /* Good RX checksums */
+#define BCDC_FLAG_SUM_NEEDED   0x08    /* Dongle needs to do TX checksums */
+#define BCDC_PRIORITY_MASK     0x7
+#define BCDC_FLAG2_IF_MASK     0x0f    /* packet rx interface in APSTA */
+#define BCDC_FLAG2_IF_SHIFT    0
+
+#define BCDC_GET_IF_IDX(hdr) \
+       ((int)((((hdr)->flags2) & BCDC_FLAG2_IF_MASK) >> BCDC_FLAG2_IF_SHIFT))
+#define BCDC_SET_IF_IDX(hdr, idx) \
+       ((hdr)->flags2 = (((hdr)->flags2 & ~BCDC_FLAG2_IF_MASK) | \
+       ((idx) << BCDC_FLAG2_IF_SHIFT)))
+
+/**
+ * struct brcmf_proto_bcdc_header - BCDC header format
+ *
+ * @flags: flags contain protocol and checksum info.
+ * @priority: 802.1d priority and USB flow control info (bit 4:7).
+ * @flags2: additional flags containing dongle interface index.
+ * @data_offset: start of packet data. header is following by firmware signals.
+ */
+struct brcmf_proto_bcdc_header {
+       u8 flags;
+       u8 priority;
+       u8 flags2;
+       u8 data_offset;
+};
+
+/*
+ * maximum length of firmware signal data between
+ * the BCDC header and packet data in the tx path.
+ */
+#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES       12
+
+#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
+#define BUS_HEADER_LEN (16+64)         /* Must be atleast SDPCM_RESERVE
+                                        * (amount of header tha might be added)
+                                        * plus any space that might be needed
+                                        * for bus alignment padding.
+                                        */
+#define ROUND_UP_MARGIN        2048    /* Biggest bus block size possible for
+                                * round off at the end of buffer
+                                * Currently is SDIO
+                                */
+
+struct brcmf_bcdc {
+       u16 reqid;
+       u8 bus_header[BUS_HEADER_LEN];
+       struct brcmf_proto_bcdc_dcmd msg;
+       unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
+};
+
+static int brcmf_proto_bcdc_msg(struct brcmf_pub *drvr)
+{
+       struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
+       int len = le32_to_cpu(bcdc->msg.len) +
+                       sizeof(struct brcmf_proto_bcdc_dcmd);
+
+       brcmf_dbg(BCDC, "Enter\n");
+
+       /* NOTE : bcdc->msg.len holds the desired length of the buffer to be
+        *        returned. Only up to BCDC_MAX_MSG_SIZE of this buffer area
+        *        is actually sent to the dongle
+        */
+       if (len > BCDC_MAX_MSG_SIZE)
+               len = BCDC_MAX_MSG_SIZE;
+
+       /* Send request */
+       return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len);
+}
+
+static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
+{
+       int ret;
+       struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
+
+       brcmf_dbg(BCDC, "Enter\n");
+       len += sizeof(struct brcmf_proto_bcdc_dcmd);
+       do {
+               ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&bcdc->msg,
+                                     len);
+               if (ret < 0)
+                       break;
+       } while (BCDC_DCMD_ID(le32_to_cpu(bcdc->msg.flags)) != id);
+
+       return ret;
+}
+
+static int
+brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
+                           void *buf, uint len)
+{
+       struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
+       struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
+       void *info;
+       int ret = 0, retries = 0;
+       u32 id, flags;
+
+       brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
+
+       memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd));
+
+       msg->cmd = cpu_to_le32(cmd);
+       msg->len = cpu_to_le32(len);
+       flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT);
+       flags = (flags & ~BCDC_DCMD_IF_MASK) |
+               (ifidx << BCDC_DCMD_IF_SHIFT);
+       msg->flags = cpu_to_le32(flags);
+
+       if (buf)
+               memcpy(bcdc->buf, buf, len);
+
+       ret = brcmf_proto_bcdc_msg(drvr);
+       if (ret < 0) {
+               brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n",
+                         ret);
+               goto done;
+       }
+
+retry:
+       /* wait for interrupt and get first fragment */
+       ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len);
+       if (ret < 0)
+               goto done;
+
+       flags = le32_to_cpu(msg->flags);
+       id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT;
+
+       if ((id < bcdc->reqid) && (++retries < RETRIES))
+               goto retry;
+       if (id != bcdc->reqid) {
+               brcmf_err("%s: unexpected request id %d (expected %d)\n",
+                         brcmf_ifname(drvr, ifidx), id, bcdc->reqid);
+               ret = -EINVAL;
+               goto done;
+       }
+
+       /* Check info buffer */
+       info = (void *)&msg[1];
+
+       /* Copy info buffer */
+       if (buf) {
+               if (ret < (int)len)
+                       len = ret;
+               memcpy(buf, info, len);
+       }
+
+       /* Check the ERROR flag */
+       if (flags & BCDC_DCMD_ERROR)
+               ret = le32_to_cpu(msg->status);
+
+done:
+       return ret;
+}
+
+static int
+brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
+                         void *buf, uint len)
+{
+       struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
+       struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
+       int ret = 0;
+       u32 flags, id;
+
+       brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
+
+       memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd));
+
+       msg->cmd = cpu_to_le32(cmd);
+       msg->len = cpu_to_le32(len);
+       flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT) | BCDC_DCMD_SET;
+       flags = (flags & ~BCDC_DCMD_IF_MASK) |
+               (ifidx << BCDC_DCMD_IF_SHIFT);
+       msg->flags = cpu_to_le32(flags);
+
+       if (buf)
+               memcpy(bcdc->buf, buf, len);
+
+       ret = brcmf_proto_bcdc_msg(drvr);
+       if (ret < 0)
+               goto done;
+
+       ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len);
+       if (ret < 0)
+               goto done;
+
+       flags = le32_to_cpu(msg->flags);
+       id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT;
+
+       if (id != bcdc->reqid) {
+               brcmf_err("%s: unexpected request id %d (expected %d)\n",
+                         brcmf_ifname(drvr, ifidx), id, bcdc->reqid);
+               ret = -EINVAL;
+               goto done;
+       }
+
+       /* Check the ERROR flag */
+       if (flags & BCDC_DCMD_ERROR)
+               ret = le32_to_cpu(msg->status);
+
+done:
+       return ret;
+}
+
+static void
+brcmf_proto_bcdc_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
+                        struct sk_buff *pktbuf)
+{
+       struct brcmf_proto_bcdc_header *h;
+
+       brcmf_dbg(BCDC, "Enter\n");
+
+       /* Push BDC header used to convey priority for buses that don't */
+       skb_push(pktbuf, BCDC_HEADER_LEN);
+
+       h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
+
+       h->flags = (BCDC_PROTO_VER << BCDC_FLAG_VER_SHIFT);
+       if (pktbuf->ip_summed == CHECKSUM_PARTIAL)
+               h->flags |= BCDC_FLAG_SUM_NEEDED;
+
+       h->priority = (pktbuf->priority & BCDC_PRIORITY_MASK);
+       h->flags2 = 0;
+       h->data_offset = offset;
+       BCDC_SET_IF_IDX(h, ifidx);
+       trace_brcmf_bcdchdr(pktbuf->data);
+}
+
+static int
+brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
+                        struct sk_buff *pktbuf)
+{
+       struct brcmf_proto_bcdc_header *h;
+
+       brcmf_dbg(BCDC, "Enter\n");
+
+       /* Pop BCDC header used to convey priority for buses that don't */
+       if (pktbuf->len <= BCDC_HEADER_LEN) {
+               brcmf_dbg(INFO, "rx data too short (%d <= %d)\n",
+                         pktbuf->len, BCDC_HEADER_LEN);
+               return -EBADE;
+       }
+
+       trace_brcmf_bcdchdr(pktbuf->data);
+       h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
+
+       *ifidx = BCDC_GET_IF_IDX(h);
+       if (*ifidx >= BRCMF_MAX_IFS) {
+               brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
+               return -EBADE;
+       }
+       /* The ifidx is the idx to map to matching netdev/ifp. When receiving
+        * events this is easy because it contains the bssidx which maps
+        * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
+        * bssidx 1 is used for p2p0 and no data can be received or
+        * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
+        */
+       if (*ifidx)
+               (*ifidx)++;
+
+       if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
+           BCDC_PROTO_VER) {
+               brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
+                         brcmf_ifname(drvr, *ifidx), h->flags);
+               return -EBADE;
+       }
+
+       if (h->flags & BCDC_FLAG_SUM_GOOD) {
+               brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
+                         brcmf_ifname(drvr, *ifidx), h->flags);
+               pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
+       }
+
+       pktbuf->priority = h->priority & BCDC_PRIORITY_MASK;
+
+       skb_pull(pktbuf, BCDC_HEADER_LEN);
+       if (do_fws)
+               brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
+       else
+               skb_pull(pktbuf, h->data_offset << 2);
+
+       if (pktbuf->len == 0)
+               return -ENODATA;
+       return 0;
+}
+
+int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
+{
+       struct brcmf_bcdc *bcdc;
+
+       bcdc = kzalloc(sizeof(*bcdc), GFP_ATOMIC);
+       if (!bcdc)
+               goto fail;
+
+       /* ensure that the msg buf directly follows the cdc msg struct */
+       if ((unsigned long)(&bcdc->msg + 1) != (unsigned long)bcdc->buf) {
+               brcmf_err("struct brcmf_proto_bcdc is not correctly defined\n");
+               goto fail;
+       }
+
+       drvr->proto->hdrpush = brcmf_proto_bcdc_hdrpush;
+       drvr->proto->hdrpull = brcmf_proto_bcdc_hdrpull;
+       drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd;
+       drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd;
+       drvr->proto->pd = bcdc;
+
+       drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
+       drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
+                       sizeof(struct brcmf_proto_bcdc_dcmd) + ROUND_UP_MARGIN;
+       return 0;
+
+fail:
+       kfree(bcdc);
+       return -ENOMEM;
+}
+
+void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr)
+{
+       kfree(drvr->proto->pd);
+       drvr->proto->pd = NULL;
+}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h
new file mode 100644 (file)
index 0000000..17e8c03
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013 Broadcom Corporation
+ *
+ * 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.
+ */
+#ifndef BRCMFMAC_BCDC_H
+#define BRCMFMAC_BCDC_H
+
+
+int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr);
+void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr);
+
+
+#endif /* BRCMFMAC_BCDC_H */
index 3e10b801eee84bc420867815ced96a3fca3428b4..91651ec7f13fedddaa7c18cce14c7654eb77404e 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/types.h>
 #include <linux/netdevice.h>
-#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 #include <linux/sched.h>
@@ -774,7 +773,6 @@ out:
 
        return ret;
 }
-EXPORT_SYMBOL(brcmf_sdio_probe);
 
 int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
 {
@@ -791,7 +789,6 @@ int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
 
        return 0;
 }
-EXPORT_SYMBOL(brcmf_sdio_remove);
 
 void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable)
 {
index abc9ceca70f3630251ad077fe307f05a8a979adc..a511c27122b8c01da665a586675fb10a74a19bfc 100644 (file)
@@ -158,10 +158,21 @@ int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
                }
        }
 
-       if (err_ret)
-               brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
-                         rw ? "write" : "read", func, regaddr, *byte, err_ret);
-
+       if (err_ret) {
+               /*
+                * SleepCSR register access can fail when
+                * waking up the device so reduce this noise
+                * in the logs.
+                */
+               if (regaddr != SBSDIO_FUNC1_SLEEPCSR)
+                       brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
+                                 rw ? "write" : "read", func, regaddr, *byte,
+                                 err_ret);
+               else
+                       brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
+                                 rw ? "write" : "read", func, regaddr, *byte,
+                                 err_ret);
+       }
        return err_ret;
 }
 
@@ -269,6 +280,9 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
 int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
 {
        int err_ret = 0;
+       struct mmc_host *host;
+       struct sdio_func *func;
+       uint max_blocks;
 
        brcmf_dbg(SDIO, "\n");
 
@@ -290,6 +304,20 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
 
        brcmf_sdioh_enablefuncs(sdiodev);
 
+       /*
+        * determine host related variables after brcmf_sdio_probe()
+        * as func->cur_blksize is properly set and F2 init has been
+        * completed successfully.
+        */
+       func = sdiodev->func[2];
+       host = func->card->host;
+       sdiodev->sg_support = host->max_segs > 1;
+       max_blocks = min_t(uint, host->max_blk_count, 511u);
+       sdiodev->max_request_size = min_t(uint, host->max_req_size,
+                                         max_blocks * func->cur_blksize);
+       sdiodev->max_segment_count = min_t(uint, host->max_segs,
+                                          SG_MAX_SINGLE_ALLOC);
+       sdiodev->max_segment_size = host->max_seg_size;
 out:
        sdio_release_host(sdiodev->func[1]);
        brcmf_dbg(SDIO, "Done\n");
@@ -318,8 +346,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
        int err;
        struct brcmf_sdio_dev *sdiodev;
        struct brcmf_bus *bus_if;
-       struct mmc_host *host;
-       uint max_blocks;
 
        brcmf_dbg(SDIO, "Enter\n");
        brcmf_dbg(SDIO, "Class=%x\n", func->class);
@@ -367,19 +393,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
                goto fail;
        }
 
-       /*
-        * determine host related variables after brcmf_sdio_probe()
-        * as func->cur_blksize is properly set and F2 init has been
-        * completed successfully.
-        */
-       host = func->card->host;
-       sdiodev->sg_support = host->max_segs > 1;
-       max_blocks = min_t(uint, host->max_blk_count, 511u);
-       sdiodev->max_request_size = min_t(uint, host->max_req_size,
-                                         max_blocks * func->cur_blksize);
-       sdiodev->max_segment_count = min_t(uint, host->max_segs,
-                                          SG_MAX_SINGLE_ALLOC);
-       sdiodev->max_segment_size = host->max_seg_size;
        brcmf_dbg(SDIO, "F2 init completed...\n");
        return 0;
 
index 899a2ada5b8212f28e30632551910b67474e6080..252024bcbc3ba736c65d18975f2b5106e026737a 100644 (file)
 
 #include "fweh.h"
 
-/*******************************************************************************
- * IO codes that are interpreted by dongle firmware
- ******************************************************************************/
-#define BRCMF_C_GET_VERSION                    1
-#define BRCMF_C_UP                             2
-#define BRCMF_C_DOWN                           3
-#define BRCMF_C_SET_PROMISC                    10
-#define BRCMF_C_GET_RATE                       12
-#define BRCMF_C_GET_INFRA                      19
-#define BRCMF_C_SET_INFRA                      20
-#define BRCMF_C_GET_AUTH                       21
-#define BRCMF_C_SET_AUTH                       22
-#define BRCMF_C_GET_BSSID                      23
-#define BRCMF_C_GET_SSID                       25
-#define BRCMF_C_SET_SSID                       26
-#define BRCMF_C_TERMINATED                     28
-#define BRCMF_C_GET_CHANNEL                    29
-#define BRCMF_C_SET_CHANNEL                    30
-#define BRCMF_C_GET_SRL                                31
-#define BRCMF_C_SET_SRL                                32
-#define BRCMF_C_GET_LRL                                33
-#define BRCMF_C_SET_LRL                                34
-#define BRCMF_C_GET_RADIO                      37
-#define BRCMF_C_SET_RADIO                      38
-#define BRCMF_C_GET_PHYTYPE                    39
-#define BRCMF_C_SET_KEY                                45
-#define BRCMF_C_SET_PASSIVE_SCAN               49
-#define BRCMF_C_SCAN                           50
-#define BRCMF_C_SCAN_RESULTS                   51
-#define BRCMF_C_DISASSOC                       52
-#define BRCMF_C_REASSOC                                53
-#define BRCMF_C_SET_ROAM_TRIGGER               55
-#define BRCMF_C_SET_ROAM_DELTA                 57
-#define BRCMF_C_GET_BCNPRD                     75
-#define BRCMF_C_SET_BCNPRD                     76
-#define BRCMF_C_GET_DTIMPRD                    77
-#define BRCMF_C_SET_DTIMPRD                    78
-#define BRCMF_C_SET_COUNTRY                    84
-#define BRCMF_C_GET_PM                         85
-#define BRCMF_C_SET_PM                         86
-#define BRCMF_C_GET_CURR_RATESET               114
-#define BRCMF_C_GET_AP                         117
-#define BRCMF_C_SET_AP                         118
-#define BRCMF_C_GET_RSSI                       127
-#define BRCMF_C_GET_WSEC                       133
-#define BRCMF_C_SET_WSEC                       134
-#define BRCMF_C_GET_PHY_NOISE                  135
-#define BRCMF_C_GET_BSS_INFO                   136
-#define BRCMF_C_GET_BANDLIST                   140
-#define BRCMF_C_SET_SCB_TIMEOUT                        158
-#define BRCMF_C_GET_PHYLIST                    180
-#define BRCMF_C_SET_SCAN_CHANNEL_TIME          185
-#define BRCMF_C_SET_SCAN_UNASSOC_TIME          187
-#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON  201
-#define BRCMF_C_GET_VALID_CHANNELS             217
-#define BRCMF_C_GET_KEY_PRIMARY                        235
-#define BRCMF_C_SET_KEY_PRIMARY                        236
-#define BRCMF_C_SET_SCAN_PASSIVE_TIME          258
-#define BRCMF_C_GET_VAR                                262
-#define BRCMF_C_SET_VAR                                263
-
-/* phy types (returned by WLC_GET_PHYTPE) */
-#define        WLC_PHY_TYPE_A          0
-#define        WLC_PHY_TYPE_B          1
-#define        WLC_PHY_TYPE_G          2
-#define        WLC_PHY_TYPE_N          4
-#define        WLC_PHY_TYPE_LP         5
-#define        WLC_PHY_TYPE_SSN        6
-#define        WLC_PHY_TYPE_HT         7
-#define        WLC_PHY_TYPE_LCN        8
-#define        WLC_PHY_TYPE_NULL       0xf
-
 #define TOE_TX_CSUM_OL         0x00000001
 #define TOE_RX_CSUM_OL         0x00000002
 
-#define        BRCMF_BSS_INFO_VERSION  109 /* curr ver of brcmf_bss_info_le struct */
-
-/* size of brcmf_scan_params not including variable length array */
-#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
-
-/* masks for channel and ssid count */
-#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
-#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
-
-/* primary (ie tx) key */
-#define BRCMF_PRIMARY_KEY      (1 << 1)
-
 /* For supporting multiple interfaces */
 #define BRCMF_MAX_IFS  16
 
-#define DOT11_BSSTYPE_ANY                      2
 #define DOT11_MAX_DEFAULT_KEYS 4
 
-#define BRCMF_ESCAN_REQ_VERSION 1
-
-#define WLC_BSS_RSSI_ON_CHANNEL                0x0002
-
-#define BRCMF_MAXRATES_IN_SET          16      /* max # of rates in rateset */
-#define BRCMF_STA_ASSOC                        0x10            /* Associated */
-
-#define BRCMF_E_STATUS_SUCCESS                 0
-#define BRCMF_E_STATUS_FAIL                    1
-#define BRCMF_E_STATUS_TIMEOUT                 2
-#define BRCMF_E_STATUS_NO_NETWORKS             3
-#define BRCMF_E_STATUS_ABORT                   4
-#define BRCMF_E_STATUS_NO_ACK                  5
-#define BRCMF_E_STATUS_UNSOLICITED             6
-#define BRCMF_E_STATUS_ATTEMPT                 7
-#define BRCMF_E_STATUS_PARTIAL                 8
-#define BRCMF_E_STATUS_NEWSCAN                 9
-#define BRCMF_E_STATUS_NEWASSOC                        10
-#define BRCMF_E_STATUS_11HQUIET                        11
-#define BRCMF_E_STATUS_SUPPRESS                        12
-#define BRCMF_E_STATUS_NOCHANS                 13
-#define BRCMF_E_STATUS_CS_ABORT                        15
-#define BRCMF_E_STATUS_ERROR                   16
-
-#define BRCMF_E_REASON_INITIAL_ASSOC           0
-#define BRCMF_E_REASON_LOW_RSSI                        1
-#define BRCMF_E_REASON_DEAUTH                  2
-#define BRCMF_E_REASON_DISASSOC                        3
-#define BRCMF_E_REASON_BCNS_LOST               4
-#define BRCMF_E_REASON_MINTXRATE               9
-#define BRCMF_E_REASON_TXFAIL                  10
-
-#define BRCMF_E_REASON_LINK_BSSCFG_DIS         4
-#define BRCMF_E_REASON_FAST_ROAM_FAILED                5
-#define BRCMF_E_REASON_DIRECTED_ROAM           6
-#define BRCMF_E_REASON_TSPEC_REJECTED          7
-#define BRCMF_E_REASON_BETTER_AP               8
-
-#define BRCMF_E_PRUNE_ENCR_MISMATCH            1
-#define BRCMF_E_PRUNE_BCAST_BSSID              2
-#define BRCMF_E_PRUNE_MAC_DENY                 3
-#define BRCMF_E_PRUNE_MAC_NA                   4
-#define BRCMF_E_PRUNE_REG_PASSV                        5
-#define BRCMF_E_PRUNE_SPCT_MGMT                        6
-#define BRCMF_E_PRUNE_RADAR                    7
-#define BRCMF_E_RSN_MISMATCH                   8
-#define BRCMF_E_PRUNE_NO_COMMON_RATES          9
-#define BRCMF_E_PRUNE_BASIC_RATES              10
-#define BRCMF_E_PRUNE_CIPHER_NA                        12
-#define BRCMF_E_PRUNE_KNOWN_STA                        13
-#define BRCMF_E_PRUNE_WDS_PEER                 15
-#define BRCMF_E_PRUNE_QBSS_LOAD                        16
-#define BRCMF_E_PRUNE_HOME_AP                  17
-
-#define BRCMF_E_SUP_OTHER                      0
-#define BRCMF_E_SUP_DECRYPT_KEY_DATA           1
-#define BRCMF_E_SUP_BAD_UCAST_WEP128           2
-#define BRCMF_E_SUP_BAD_UCAST_WEP40            3
-#define BRCMF_E_SUP_UNSUP_KEY_LEN              4
-#define BRCMF_E_SUP_PW_KEY_CIPHER              5
-#define BRCMF_E_SUP_MSG3_TOO_MANY_IE           6
-#define BRCMF_E_SUP_MSG3_IE_MISMATCH           7
-#define BRCMF_E_SUP_NO_INSTALL_FLAG            8
-#define BRCMF_E_SUP_MSG3_NO_GTK                        9
-#define BRCMF_E_SUP_GRP_KEY_CIPHER             10
-#define BRCMF_E_SUP_GRP_MSG1_NO_GTK            11
-#define BRCMF_E_SUP_GTK_DECRYPT_FAIL           12
-#define BRCMF_E_SUP_SEND_FAIL                  13
-#define BRCMF_E_SUP_DEAUTH                     14
-
-#define BRCMF_E_IF_ADD                         1
-#define BRCMF_E_IF_DEL                         2
-#define BRCMF_E_IF_CHANGE                      3
-
-#define BRCMF_E_IF_FLAG_NOIF                   1
-
-#define BRCMF_E_IF_ROLE_STA                    0
-#define BRCMF_E_IF_ROLE_AP                     1
-#define BRCMF_E_IF_ROLE_WDS                    2
-
-#define BRCMF_E_LINK_BCN_LOSS                  1
-#define BRCMF_E_LINK_DISASSOC                  2
-#define BRCMF_E_LINK_ASSOC_REC                 3
-#define BRCMF_E_LINK_BSSCFG_DIS                        4
-
 /* Small, medium and maximum buffer size for dcmd
  */
 #define BRCMF_DCMD_SMLEN       256
 
 #define BRCMF_AMPDU_RX_REORDER_MAXFLOWS                256
 
-/* Pattern matching filter. Specifies an offset within received packets to
- * start matching, the pattern to match, the size of the pattern, and a bitmask
- * that indicates which bits within the pattern should be matched.
- */
-struct brcmf_pkt_filter_pattern_le {
-       /*
-        * Offset within received packet to start pattern matching.
-        * Offset '0' is the first byte of the ethernet header.
-        */
-       __le32 offset;
-       /* Size of the pattern.  Bitmask must be the same size.*/
-       __le32 size_bytes;
-       /*
-        * Variable length mask and pattern data. mask starts at offset 0.
-        * Pattern immediately follows mask.
-        */
-       u8 mask_and_pattern[1];
-};
-
-/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
-struct brcmf_pkt_filter_le {
-       __le32 id;              /* Unique filter id, specified by app. */
-       __le32 type;            /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
-       __le32 negate_match;    /* Negate the result of filter matches */
-       union {                 /* Filter definitions */
-               struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
-       } u;
-};
-
-/* IOVAR "pkt_filter_enable" parameter. */
-struct brcmf_pkt_filter_enable_le {
-       __le32 id;              /* Unique filter id */
-       __le32 enable;          /* Enable/disable bool */
-};
-
-/* BSS info structure
- * Applications MUST CHECK ie_offset field and length field to access IEs and
- * next bss_info structure in a vector (in struct brcmf_scan_results)
- */
-struct brcmf_bss_info_le {
-       __le32 version;         /* version field */
-       __le32 length;          /* byte length of data in this record,
-                                * starting at version and including IEs
-                                */
-       u8 BSSID[ETH_ALEN];
-       __le16 beacon_period;   /* units are Kusec */
-       __le16 capability;      /* Capability information */
-       u8 SSID_len;
-       u8 SSID[32];
-       struct {
-               __le32 count;   /* # rates in this set */
-               u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
-       } rateset;              /* supported rates */
-       __le16 chanspec;        /* chanspec for bss */
-       __le16 atim_window;     /* units are Kusec */
-       u8 dtim_period; /* DTIM period */
-       __le16 RSSI;            /* receive signal strength (in dBm) */
-       s8 phy_noise;           /* noise (in dBm) */
-
-       u8 n_cap;               /* BSS is 802.11N Capable */
-       /* 802.11N BSS Capabilities (based on HT_CAP_*): */
-       __le32 nbss_cap;
-       u8 ctl_ch;              /* 802.11N BSS control channel number */
-       __le32 reserved32[1];   /* Reserved for expansion of BSS properties */
-       u8 flags;               /* flags */
-       u8 reserved[3]; /* Reserved for expansion of BSS properties */
-       u8 basic_mcs[MCSSET_LEN];       /* 802.11N BSS required MCS set */
-
-       __le16 ie_offset;       /* offset at which IEs start, from beginning */
-       __le32 ie_length;       /* byte length of Information Elements */
-       __le16 SNR;             /* average SNR of during frame reception */
-       /* Add new fields here */
-       /* variable length Information Elements */
-};
-
-struct brcm_rateset_le {
-       /* # rates in this set */
-       __le32 count;
-       /* rates in 500kbps units w/hi bit set if basic */
-       u8 rates[BRCMF_MAXRATES_IN_SET];
-};
-
-struct brcmf_ssid {
-       u32 SSID_len;
-       unsigned char SSID[32];
-};
-
-struct brcmf_ssid_le {
-       __le32 SSID_len;
-       unsigned char SSID[32];
-};
-
-struct brcmf_scan_params_le {
-       struct brcmf_ssid_le ssid_le;   /* default: {0, ""} */
-       u8 bssid[ETH_ALEN];     /* default: bcast */
-       s8 bss_type;            /* default: any,
-                                * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
-                                */
-       u8 scan_type;   /* flags, 0 use default */
-       __le32 nprobes;   /* -1 use default, number of probes per channel */
-       __le32 active_time;     /* -1 use default, dwell time per channel for
-                                * active scanning
-                                */
-       __le32 passive_time;    /* -1 use default, dwell time per channel
-                                * for passive scanning
-                                */
-       __le32 home_time;       /* -1 use default, dwell time for the
-                                * home channel between channel scans
-                                */
-       __le32 channel_num;     /* count of channels and ssids that follow
-                                *
-                                * low half is count of channels in
-                                * channel_list, 0 means default (use all
-                                * available channels)
-                                *
-                                * high half is entries in struct brcmf_ssid
-                                * array that follows channel_list, aligned for
-                                * s32 (4 bytes) meaning an odd channel count
-                                * implies a 2-byte pad between end of
-                                * channel_list and first ssid
-                                *
-                                * if ssid count is zero, single ssid in the
-                                * fixed parameter portion is assumed, otherwise
-                                * ssid in the fixed portion is ignored
-                                */
-       __le16 channel_list[1]; /* list of chanspecs */
-};
-
-struct brcmf_scan_results {
-       u32 buflen;
-       u32 version;
-       u32 count;
-       struct brcmf_bss_info_le bss_info_le[];
-};
-
-struct brcmf_escan_params_le {
-       __le32 version;
-       __le16 action;
-       __le16 sync_id;
-       struct brcmf_scan_params_le params_le;
-};
-
-struct brcmf_escan_result_le {
-       __le32 buflen;
-       __le32 version;
-       __le16 sync_id;
-       __le16 bss_count;
-       struct brcmf_bss_info_le bss_info_le;
-};
-
-#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \
-       sizeof(struct brcmf_bss_info_le))
-
-/* used for association with a specific BSSID and chanspec list */
-struct brcmf_assoc_params_le {
-       /* 00:00:00:00:00:00: broadcast scan */
-       u8 bssid[ETH_ALEN];
-       /* 0: all available channels, otherwise count of chanspecs in
-        * chanspec_list */
-       __le32 chanspec_num;
-       /* list of chanspecs */
-       __le16 chanspec_list[1];
-};
-
-/* used for join with or without a specific bssid and channel list */
-struct brcmf_join_params {
-       struct brcmf_ssid_le ssid_le;
-       struct brcmf_assoc_params_le params_le;
-};
-
-/* scan params for extended join */
-struct brcmf_join_scan_params_le {
-       u8 scan_type;           /* 0 use default, active or passive scan */
-       __le32 nprobes;         /* -1 use default, nr of probes per channel */
-       __le32 active_time;     /* -1 use default, dwell time per channel for
-                                * active scanning
-                                */
-       __le32 passive_time;    /* -1 use default, dwell time per channel
-                                * for passive scanning
-                                */
-       __le32 home_time;       /* -1 use default, dwell time for the home
-                                * channel between channel scans
-                                */
-};
-
-/* extended join params */
-struct brcmf_ext_join_params_le {
-       struct brcmf_ssid_le ssid_le;   /* {0, ""}: wildcard scan */
-       struct brcmf_join_scan_params_le scan_le;
-       struct brcmf_assoc_params_le assoc_le;
-};
-
-struct brcmf_wsec_key {
-       u32 index;              /* key index */
-       u32 len;                /* key length */
-       u8 data[WLAN_MAX_KEY_LEN];      /* key data */
-       u32 pad_1[18];
-       u32 algo;       /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
-       u32 flags;      /* misc flags */
-       u32 pad_2[3];
-       u32 iv_initialized;     /* has IV been initialized already? */
-       u32 pad_3;
-       /* Rx IV */
-       struct {
-               u32 hi; /* upper 32 bits of IV */
-               u16 lo; /* lower 16 bits of IV */
-       } rxiv;
-       u32 pad_4[2];
-       u8 ea[ETH_ALEN];        /* per station */
-};
-
-/*
- * dongle requires same struct as above but with fields in little endian order
+/* Length of firmware version string stored for
+ * ethtool driver info which uses 32 bytes as well.
  */
-struct brcmf_wsec_key_le {
-       __le32 index;           /* key index */
-       __le32 len;             /* key length */
-       u8 data[WLAN_MAX_KEY_LEN];      /* key data */
-       __le32 pad_1[18];
-       __le32 algo;    /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
-       __le32 flags;   /* misc flags */
-       __le32 pad_2[3];
-       __le32 iv_initialized;  /* has IV been initialized already? */
-       __le32 pad_3;
-       /* Rx IV */
-       struct {
-               __le32 hi;      /* upper 32 bits of IV */
-               __le16 lo;      /* lower 16 bits of IV */
-       } rxiv;
-       __le32 pad_4[2];
-       u8 ea[ETH_ALEN];        /* per station */
-};
-
-/* Used to get specific STA parameters */
-struct brcmf_scb_val_le {
-       __le32 val;
-       u8 ea[ETH_ALEN];
-};
-
-/* channel encoding */
-struct brcmf_channel_info_le {
-       __le32 hw_channel;
-       __le32 target_channel;
-       __le32 scan_channel;
-};
-
-struct brcmf_sta_info_le {
-       __le16  ver;            /* version of this struct */
-       __le16  len;            /* length in bytes of this structure */
-       __le16  cap;            /* sta's advertised capabilities */
-       __le32  flags;          /* flags defined below */
-       __le32  idle;           /* time since data pkt rx'd from sta */
-       u8      ea[ETH_ALEN];           /* Station address */
-       __le32  count;                  /* # rates in this set */
-       u8      rates[BRCMF_MAXRATES_IN_SET];   /* rates in 500kbps units */
-                                               /* w/hi bit set if basic */
-       __le32  in;             /* seconds elapsed since associated */
-       __le32  listen_interval_inms; /* Min Listen interval in ms for STA */
-       __le32  tx_pkts;        /* # of packets transmitted */
-       __le32  tx_failures;    /* # of packets failed */
-       __le32  rx_ucast_pkts;  /* # of unicast packets received */
-       __le32  rx_mcast_pkts;  /* # of multicast packets received */
-       __le32  tx_rate;        /* Rate of last successful tx frame */
-       __le32  rx_rate;        /* Rate of last successful rx frame */
-       __le32  rx_decrypt_succeeds;    /* # of packet decrypted successfully */
-       __le32  rx_decrypt_failures;    /* # of packet decrypted failed */
-};
-
-struct brcmf_chanspec_list {
-       __le32  count;          /* # of entries */
-       __le32  element[1];     /* variable length uint32 list */
-};
-
-/*
- * WLC_E_PROBRESP_MSG
- * WLC_E_P2P_PROBREQ_MSG
- * WLC_E_ACTION_FRAME_RX
- */
-struct brcmf_rx_mgmt_data {
-       __be16  version;
-       __be16  chanspec;
-       __be32  rssi;
-       __be32  mactime;
-       __be32  rate;
-};
+#define BRCMF_DRIVER_FIRMWARE_VERSION_LEN      32
 
 /* Bus independent dongle command */
 struct brcmf_dcmd {
@@ -535,7 +84,7 @@ struct brcmf_fws_info; /* firmware signalling info */
 struct brcmf_pub {
        /* Linkage ponters */
        struct brcmf_bus *bus_if;
-       struct brcmf_proto *prot;
+       struct brcmf_proto *proto;
        struct brcmf_cfg80211_info *config;
 
        /* Internal brcmf items */
@@ -544,7 +93,7 @@ struct brcmf_pub {
        u8 wme_dp;              /* wme discard priority */
 
        /* Dongle media info */
-       unsigned long drv_version;      /* Version of dongle-resident driver */
+       char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN];
        u8 mac[ETH_ALEN];               /* MAC address obtained from dongle */
 
        /* Multicast data packets sent to dongle */
@@ -566,14 +115,6 @@ struct brcmf_pub {
 #endif
 };
 
-struct brcmf_if_event {
-       u8 ifidx;
-       u8 action;
-       u8 flags;
-       u8 bssidx;
-       u8 role;
-};
-
 /* forward declarations */
 struct brcmf_cfg80211_vif;
 struct brcmf_fws_mac_descriptor;
@@ -635,16 +176,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
 /* Return pointer to interface name */
 char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
 
-/* Query dongle */
-int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
-                              void *buf, uint len);
-int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
-                            void *buf, uint len);
-
-/* Remove any protocol-specific data header. */
-int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
-                       struct sk_buff *rxp);
-
 int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
 struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
                              char *name, u8 *mac_addr);
@@ -655,4 +186,7 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp);
 void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
                      bool success);
 
+/* Sets dongle media info (drv_version, mac address). */
+int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
+
 #endif                         /* _BRCMF_H_ */
index a6eb09e5d46f408acf9205937ebffd772b15846d..6a54905528befd0238ce198acdbd6f9d642d1340 100644 (file)
@@ -34,6 +34,7 @@ struct brcmf_bus_dcmd {
 /**
  * struct brcmf_bus_ops - bus callback operations.
  *
+ * @preinit: execute bus/device specific dongle init commands (optional).
  * @init: prepare for communication with dongle.
  * @stop: clear pending frames, disable data flow.
  * @txdata: send a data frame to the dongle. When the data
@@ -51,6 +52,7 @@ struct brcmf_bus_dcmd {
  * indicated otherwise these callbacks are mandatory.
  */
 struct brcmf_bus_ops {
+       int (*preinit)(struct device *dev);
        int (*init)(struct device *dev);
        void (*stop)(struct device *dev);
        int (*txdata)(struct device *dev, struct sk_buff *skb);
@@ -85,7 +87,6 @@ struct brcmf_bus {
        unsigned long tx_realloc;
        u32 chip;
        u32 chiprev;
-       struct list_head dcmd_list;
 
        struct brcmf_bus_ops *ops;
 };
@@ -93,6 +94,13 @@ struct brcmf_bus {
 /*
  * callback wrappers
  */
+static inline int brcmf_bus_preinit(struct brcmf_bus *bus)
+{
+       if (!bus->ops->preinit)
+               return 0;
+       return bus->ops->preinit(bus->dev);
+}
+
 static inline int brcmf_bus_init(struct brcmf_bus *bus)
 {
        return bus->ops->init(bus->dev);
@@ -139,7 +147,7 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt,
 void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
 
 /* Indication from bus module regarding presence/insertion of dongle. */
-int brcmf_attach(uint bus_hdrlen, struct device *dev);
+int brcmf_attach(struct device *dev);
 /* Indication from bus module regarding removal/absence of dongle */
 void brcmf_detach(struct device *dev);
 /* Indication from bus module that dongle should be reset */
@@ -151,6 +159,9 @@ void brcmf_txflowblock(struct device *dev, bool state);
 void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
 
 int brcmf_bus_start(struct device *dev);
+s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data,
+                               u32 len);
+void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
 
 #ifdef CONFIG_BRCMFMAC_SDIO
 void brcmf_sdio_exit(void);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
deleted file mode 100644 (file)
index dd85401..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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.
- */
-
-/*******************************************************************************
- * Communicates with the dongle by using dcmd codes.
- * For certain dcmd codes, the dongle interprets string data from the host.
- ******************************************************************************/
-
-#include <linux/types.h>
-#include <linux/netdevice.h>
-
-#include <brcmu_utils.h>
-#include <brcmu_wifi.h>
-
-#include "dhd.h"
-#include "dhd_proto.h"
-#include "dhd_bus.h"
-#include "fwsignal.h"
-#include "dhd_dbg.h"
-#include "tracepoint.h"
-
-struct brcmf_proto_cdc_dcmd {
-       __le32 cmd;     /* dongle command value */
-       __le32 len;     /* lower 16: output buflen;
-                        * upper 16: input buflen (excludes header) */
-       __le32 flags;   /* flag defns given below */
-       __le32 status;  /* status code returned from the device */
-};
-
-/* Max valid buffer size that can be sent to the dongle */
-#define CDC_MAX_MSG_SIZE       (ETH_FRAME_LEN+ETH_FCS_LEN)
-
-/* CDC flag definitions */
-#define CDC_DCMD_ERROR         0x01    /* 1=cmd failed */
-#define CDC_DCMD_SET           0x02    /* 0=get, 1=set cmd */
-#define CDC_DCMD_IF_MASK       0xF000          /* I/F index */
-#define CDC_DCMD_IF_SHIFT      12
-#define CDC_DCMD_ID_MASK       0xFFFF0000      /* id an cmd pairing */
-#define CDC_DCMD_ID_SHIFT      16              /* ID Mask shift bits */
-#define CDC_DCMD_ID(flags)     \
-       (((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
-
-/*
- * BDC header - Broadcom specific extension of CDC.
- * Used on data packets to convey priority across USB.
- */
-#define        BDC_HEADER_LEN          4
-#define BDC_PROTO_VER          2       /* Protocol version */
-#define BDC_FLAG_VER_MASK      0xf0    /* Protocol version mask */
-#define BDC_FLAG_VER_SHIFT     4       /* Protocol version shift */
-#define BDC_FLAG_SUM_GOOD      0x04    /* Good RX checksums */
-#define BDC_FLAG_SUM_NEEDED    0x08    /* Dongle needs to do TX checksums */
-#define BDC_PRIORITY_MASK      0x7
-#define BDC_FLAG2_IF_MASK      0x0f    /* packet rx interface in APSTA */
-#define BDC_FLAG2_IF_SHIFT     0
-
-#define BDC_GET_IF_IDX(hdr) \
-       ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
-#define BDC_SET_IF_IDX(hdr, idx) \
-       ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
-       ((idx) << BDC_FLAG2_IF_SHIFT)))
-
-/**
- * struct brcmf_proto_bdc_header - BDC header format
- *
- * @flags: flags contain protocol and checksum info.
- * @priority: 802.1d priority and USB flow control info (bit 4:7).
- * @flags2: additional flags containing dongle interface index.
- * @data_offset: start of packet data. header is following by firmware signals.
- */
-struct brcmf_proto_bdc_header {
-       u8 flags;
-       u8 priority;
-       u8 flags2;
-       u8 data_offset;
-};
-
-/*
- * maximum length of firmware signal data between
- * the BDC header and packet data in the tx path.
- */
-#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES       12
-
-#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
-#define BUS_HEADER_LEN (16+64)         /* Must be atleast SDPCM_RESERVE
-                                        * (amount of header tha might be added)
-                                        * plus any space that might be needed
-                                        * for bus alignment padding.
-                                        */
-#define ROUND_UP_MARGIN        2048    /* Biggest bus block size possible for
-                                * round off at the end of buffer
-                                * Currently is SDIO
-                                */
-
-struct brcmf_proto {
-       u16 reqid;
-       u8 bus_header[BUS_HEADER_LEN];
-       struct brcmf_proto_cdc_dcmd msg;
-       unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
-};
-
-static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
-{
-       struct brcmf_proto *prot = drvr->prot;
-       int len = le32_to_cpu(prot->msg.len) +
-                       sizeof(struct brcmf_proto_cdc_dcmd);
-
-       brcmf_dbg(CDC, "Enter\n");
-
-       /* NOTE : cdc->msg.len holds the desired length of the buffer to be
-        *        returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
-        *        is actually sent to the dongle
-        */
-       if (len > CDC_MAX_MSG_SIZE)
-               len = CDC_MAX_MSG_SIZE;
-
-       /* Send request */
-       return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&prot->msg, len);
-}
-
-static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
-{
-       int ret;
-       struct brcmf_proto *prot = drvr->prot;
-
-       brcmf_dbg(CDC, "Enter\n");
-       len += sizeof(struct brcmf_proto_cdc_dcmd);
-       do {
-               ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg,
-                                     len);
-               if (ret < 0)
-                       break;
-       } while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
-
-       return ret;
-}
-
-int
-brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
-                              void *buf, uint len)
-{
-       struct brcmf_proto *prot = drvr->prot;
-       struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
-       void *info;
-       int ret = 0, retries = 0;
-       u32 id, flags;
-
-       brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len);
-
-       memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
-
-       msg->cmd = cpu_to_le32(cmd);
-       msg->len = cpu_to_le32(len);
-       flags = (++prot->reqid << CDC_DCMD_ID_SHIFT);
-       flags = (flags & ~CDC_DCMD_IF_MASK) |
-               (ifidx << CDC_DCMD_IF_SHIFT);
-       msg->flags = cpu_to_le32(flags);
-
-       if (buf)
-               memcpy(prot->buf, buf, len);
-
-       ret = brcmf_proto_cdc_msg(drvr);
-       if (ret < 0) {
-               brcmf_err("brcmf_proto_cdc_msg failed w/status %d\n",
-                         ret);
-               goto done;
-       }
-
-retry:
-       /* wait for interrupt and get first fragment */
-       ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
-       if (ret < 0)
-               goto done;
-
-       flags = le32_to_cpu(msg->flags);
-       id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
-
-       if ((id < prot->reqid) && (++retries < RETRIES))
-               goto retry;
-       if (id != prot->reqid) {
-               brcmf_err("%s: unexpected request id %d (expected %d)\n",
-                         brcmf_ifname(drvr, ifidx), id, prot->reqid);
-               ret = -EINVAL;
-               goto done;
-       }
-
-       /* Check info buffer */
-       info = (void *)&msg[1];
-
-       /* Copy info buffer */
-       if (buf) {
-               if (ret < (int)len)
-                       len = ret;
-               memcpy(buf, info, len);
-       }
-
-       /* Check the ERROR flag */
-       if (flags & CDC_DCMD_ERROR)
-               ret = le32_to_cpu(msg->status);
-
-done:
-       return ret;
-}
-
-int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
-                                void *buf, uint len)
-{
-       struct brcmf_proto *prot = drvr->prot;
-       struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
-       int ret = 0;
-       u32 flags, id;
-
-       brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len);
-
-       memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
-
-       msg->cmd = cpu_to_le32(cmd);
-       msg->len = cpu_to_le32(len);
-       flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET;
-       flags = (flags & ~CDC_DCMD_IF_MASK) |
-               (ifidx << CDC_DCMD_IF_SHIFT);
-       msg->flags = cpu_to_le32(flags);
-
-       if (buf)
-               memcpy(prot->buf, buf, len);
-
-       ret = brcmf_proto_cdc_msg(drvr);
-       if (ret < 0)
-               goto done;
-
-       ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
-       if (ret < 0)
-               goto done;
-
-       flags = le32_to_cpu(msg->flags);
-       id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
-
-       if (id != prot->reqid) {
-               brcmf_err("%s: unexpected request id %d (expected %d)\n",
-                         brcmf_ifname(drvr, ifidx), id, prot->reqid);
-               ret = -EINVAL;
-               goto done;
-       }
-
-       /* Check the ERROR flag */
-       if (flags & CDC_DCMD_ERROR)
-               ret = le32_to_cpu(msg->status);
-
-done:
-       return ret;
-}
-
-static bool pkt_sum_needed(struct sk_buff *skb)
-{
-       return skb->ip_summed == CHECKSUM_PARTIAL;
-}
-
-static void pkt_set_sum_good(struct sk_buff *skb, bool x)
-{
-       skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
-}
-
-void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
-                        struct sk_buff *pktbuf)
-{
-       struct brcmf_proto_bdc_header *h;
-
-       brcmf_dbg(CDC, "Enter\n");
-
-       /* Push BDC header used to convey priority for buses that don't */
-       skb_push(pktbuf, BDC_HEADER_LEN);
-
-       h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
-
-       h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
-       if (pkt_sum_needed(pktbuf))
-               h->flags |= BDC_FLAG_SUM_NEEDED;
-
-       h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
-       h->flags2 = 0;
-       h->data_offset = offset;
-       BDC_SET_IF_IDX(h, ifidx);
-       trace_brcmf_bdchdr(pktbuf->data);
-}
-
-int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
-                       struct sk_buff *pktbuf)
-{
-       struct brcmf_proto_bdc_header *h;
-
-       brcmf_dbg(CDC, "Enter\n");
-
-       /* Pop BDC header used to convey priority for buses that don't */
-
-       if (pktbuf->len <= BDC_HEADER_LEN) {
-               brcmf_dbg(INFO, "rx data too short (%d <= %d)\n",
-                         pktbuf->len, BDC_HEADER_LEN);
-               return -EBADE;
-       }
-
-       trace_brcmf_bdchdr(pktbuf->data);
-       h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
-
-       *ifidx = BDC_GET_IF_IDX(h);
-       if (*ifidx >= BRCMF_MAX_IFS) {
-               brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
-               return -EBADE;
-       }
-       /* The ifidx is the idx to map to matching netdev/ifp. When receiving
-        * events this is easy because it contains the bssidx which maps
-        * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
-        * bssidx 1 is used for p2p0 and no data can be received or
-        * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
-        */
-       if (*ifidx)
-               (*ifidx)++;
-
-       if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
-           BDC_PROTO_VER) {
-               brcmf_err("%s: non-BDC packet received, flags 0x%x\n",
-                         brcmf_ifname(drvr, *ifidx), h->flags);
-               return -EBADE;
-       }
-
-       if (h->flags & BDC_FLAG_SUM_GOOD) {
-               brcmf_dbg(CDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
-                         brcmf_ifname(drvr, *ifidx), h->flags);
-               pkt_set_sum_good(pktbuf, true);
-       }
-
-       pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
-
-       skb_pull(pktbuf, BDC_HEADER_LEN);
-       if (do_fws)
-               brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
-       else
-               skb_pull(pktbuf, h->data_offset << 2);
-
-       if (pktbuf->len == 0)
-               return -ENODATA;
-       return 0;
-}
-
-int brcmf_proto_attach(struct brcmf_pub *drvr)
-{
-       struct brcmf_proto *cdc;
-
-       cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
-       if (!cdc)
-               goto fail;
-
-       /* ensure that the msg buf directly follows the cdc msg struct */
-       if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
-               brcmf_err("struct brcmf_proto is not correctly defined\n");
-               goto fail;
-       }
-
-       drvr->prot = cdc;
-       drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
-       drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
-                       sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
-       return 0;
-
-fail:
-       kfree(cdc);
-       return -ENOMEM;
-}
-
-/* ~NOTE~ What if another thread is waiting on the semaphore?  Holding it? */
-void brcmf_proto_detach(struct brcmf_pub *drvr)
-{
-       kfree(drvr->prot);
-       drvr->prot = NULL;
-}
-
-void brcmf_proto_stop(struct brcmf_pub *drvr)
-{
-       /* Nothing to do for CDC */
-}
index 9431af2465f3135fc76d5df370853a3b85a77d67..548dbb5542c63eb2631aafa8b2344013bfd90752 100644 (file)
@@ -21,9 +21,9 @@
 #include <brcmu_utils.h>
 #include "dhd.h"
 #include "dhd_bus.h"
-#include "dhd_proto.h"
 #include "dhd_dbg.h"
 #include "fwil.h"
+#include "fwil_types.h"
 #include "tracepoint.h"
 
 #define PKTFILTER_BUF_SIZE             128
@@ -257,8 +257,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
        u8 buf[BRCMF_DCMD_SMLEN];
        char *ptr;
        s32 err;
-       struct brcmf_bus_dcmd *cmdlst;
-       struct list_head *cur, *q;
 
        /* retreive mac address */
        err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
@@ -281,9 +279,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
        }
        ptr = (char *)buf;
        strsep(&ptr, "\n");
+
        /* Print fw version info */
        brcmf_err("Firmware version = %s\n", buf);
 
+       /* locate firmware version number for ethtool */
+       ptr = strrchr(buf, ' ') + 1;
+       strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
+
        /*
         * Setup timeout if Beacons are lost and roam is off to report
         * link down
@@ -342,17 +345,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
        brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
                                         0, true);
 
-       /* set bus specific command if there is any */
-       list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) {
-               cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list);
-               if (cmdlst->name && cmdlst->param && cmdlst->param_len) {
-                       brcmf_fil_iovar_data_set(ifp, cmdlst->name,
-                                                cmdlst->param,
-                                                cmdlst->param_len);
-               }
-               list_del(cur);
-               kfree(cmdlst);
-       }
+       /* do bus specific preinit here */
+       err = brcmf_bus_preinit(ifp->drvr->bus_if);
 done:
        return err;
 }
index 0f9e9057e7dd2dea3868383990bf67b16cc23a65..03fe8aca4d3261c81f704f89853364f0f0bb7507 100644 (file)
@@ -22,7 +22,6 @@
 #include "dhd.h"
 #include "dhd_bus.h"
 #include "dhd_dbg.h"
-#include "tracepoint.h"
 
 static struct dentry *root_folder;
 
@@ -42,6 +41,40 @@ void brcmf_debugfs_exit(void)
        root_folder = NULL;
 }
 
+static
+ssize_t brcmf_debugfs_chipinfo_read(struct file *f, char __user *data,
+                                  size_t count, loff_t *ppos)
+{
+       struct brcmf_pub *drvr = f->private_data;
+       struct brcmf_bus *bus = drvr->bus_if;
+       char buf[40];
+       int res;
+
+       /* only allow read from start */
+       if (*ppos > 0)
+               return 0;
+
+       res = scnprintf(buf, sizeof(buf), "chip: %x(%u) rev %u\n",
+                       bus->chip, bus->chip, bus->chiprev);
+       return simple_read_from_buffer(data, count, ppos, buf, res);
+}
+
+static const struct file_operations brcmf_debugfs_chipinfo_ops = {
+       .owner = THIS_MODULE,
+       .open = simple_open,
+       .read = brcmf_debugfs_chipinfo_read
+};
+
+static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr)
+{
+       struct dentry *dentry =  drvr->dbgfs_dir;
+
+       if (!IS_ERR_OR_NULL(dentry))
+               debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr,
+                                   &brcmf_debugfs_chipinfo_ops);
+       return 0;
+}
+
 int brcmf_debugfs_attach(struct brcmf_pub *drvr)
 {
        struct device *dev = drvr->bus_if->dev;
@@ -50,6 +83,7 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
                return -ENODEV;
 
        drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
+       brcmf_debugfs_create_chipinfo(drvr);
        return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
 }
 
index 0af1f5dc583a8fd7dd9a550b6e3e5f585ab64925..ef52ed7abc69349640081292f5f862277900607c 100644 (file)
@@ -33,7 +33,7 @@
 #define BRCMF_USB_VAL  0x00002000
 #define BRCMF_SCAN_VAL 0x00004000
 #define BRCMF_CONN_VAL 0x00008000
-#define BRCMF_CDC_VAL  0x00010000
+#define BRCMF_BCDC_VAL 0x00010000
 #define BRCMF_SDIO_VAL 0x00020000
 
 /* set default print format */
index 64e9cff241b9156745bab110010520bfba730394..bce0b8e511fd22eb085077169050426f42714838 100644 (file)
 
 #include "dhd.h"
 #include "dhd_bus.h"
-#include "dhd_proto.h"
 #include "dhd_dbg.h"
 #include "fwil_types.h"
 #include "p2p.h"
 #include "wl_cfg80211.h"
 #include "fwil.h"
 #include "fwsignal.h"
+#include "proto.h"
 
 MODULE_AUTHOR("Broadcom Corporation");
 MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
@@ -592,28 +592,6 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
        return &ifp->stats;
 }
 
-/*
- * Set current toe component enables in toe_ol iovar,
- * and set toe global enable iovar
- */
-static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol)
-{
-       s32 err;
-
-       err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol);
-       if (err < 0) {
-               brcmf_err("Setting toe_ol failed, %d\n", err);
-               return err;
-       }
-
-       err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0));
-       if (err < 0)
-               brcmf_err("Setting toe failed, %d\n", err);
-
-       return err;
-
-}
-
 static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
                                    struct ethtool_drvinfo *info)
 {
@@ -621,8 +599,8 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
        struct brcmf_pub *drvr = ifp->drvr;
 
        strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
-       snprintf(info->version, sizeof(info->version), "%lu",
-                drvr->drv_version);
+       snprintf(info->version, sizeof(info->version), "n/a");
+       strlcpy(info->fw_version, drvr->fwver, sizeof(info->fw_version));
        strlcpy(info->bus_info, dev_name(drvr->bus_if->dev),
                sizeof(info->bus_info));
 }
@@ -631,124 +609,6 @@ static const struct ethtool_ops brcmf_ethtool_ops = {
        .get_drvinfo = brcmf_ethtool_get_drvinfo,
 };
 
-static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
-{
-       struct brcmf_pub *drvr = ifp->drvr;
-       struct ethtool_drvinfo info;
-       char drvname[sizeof(info.driver)];
-       u32 cmd;
-       struct ethtool_value edata;
-       u32 toe_cmpnt, csum_dir;
-       int ret;
-
-       brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
-
-       /* all ethtool calls start with a cmd word */
-       if (copy_from_user(&cmd, uaddr, sizeof(u32)))
-               return -EFAULT;
-
-       switch (cmd) {
-       case ETHTOOL_GDRVINFO:
-               /* Copy out any request driver name */
-               if (copy_from_user(&info, uaddr, sizeof(info)))
-                       return -EFAULT;
-               strncpy(drvname, info.driver, sizeof(info.driver));
-               drvname[sizeof(info.driver) - 1] = '\0';
-
-               /* clear struct for return */
-               memset(&info, 0, sizeof(info));
-               info.cmd = cmd;
-
-               /* if requested, identify ourselves */
-               if (strcmp(drvname, "?dhd") == 0) {
-                       sprintf(info.driver, "dhd");
-                       strcpy(info.version, BRCMF_VERSION_STR);
-               }
-               /* report dongle driver type */
-               else
-                       sprintf(info.driver, "wl");
-
-               sprintf(info.version, "%lu", drvr->drv_version);
-               if (copy_to_user(uaddr, &info, sizeof(info)))
-                       return -EFAULT;
-               brcmf_dbg(TRACE, "given %*s, returning %s\n",
-                         (int)sizeof(drvname), drvname, info.driver);
-               break;
-
-               /* Get toe offload components from dongle */
-       case ETHTOOL_GRXCSUM:
-       case ETHTOOL_GTXCSUM:
-               ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
-               if (ret < 0)
-                       return ret;
-
-               csum_dir =
-                   (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
-
-               edata.cmd = cmd;
-               edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
-
-               if (copy_to_user(uaddr, &edata, sizeof(edata)))
-                       return -EFAULT;
-               break;
-
-               /* Set toe offload components in dongle */
-       case ETHTOOL_SRXCSUM:
-       case ETHTOOL_STXCSUM:
-               if (copy_from_user(&edata, uaddr, sizeof(edata)))
-                       return -EFAULT;
-
-               /* Read the current settings, update and write back */
-               ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
-               if (ret < 0)
-                       return ret;
-
-               csum_dir =
-                   (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
-
-               if (edata.data != 0)
-                       toe_cmpnt |= csum_dir;
-               else
-                       toe_cmpnt &= ~csum_dir;
-
-               ret = brcmf_toe_set(ifp, toe_cmpnt);
-               if (ret < 0)
-                       return ret;
-
-               /* If setting TX checksum mode, tell Linux the new mode */
-               if (cmd == ETHTOOL_STXCSUM) {
-                       if (edata.data)
-                               ifp->ndev->features |= NETIF_F_IP_CSUM;
-                       else
-                               ifp->ndev->features &= ~NETIF_F_IP_CSUM;
-               }
-
-               break;
-
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       return 0;
-}
-
-static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
-                                   int cmd)
-{
-       struct brcmf_if *ifp = netdev_priv(ndev);
-       struct brcmf_pub *drvr = ifp->drvr;
-
-       brcmf_dbg(TRACE, "Enter, idx=%d, cmd=0x%04x\n", ifp->bssidx, cmd);
-
-       if (!drvr->iflist[ifp->bssidx])
-               return -1;
-
-       if (cmd == SIOCETHTOOL)
-               return brcmf_ethtool(ifp, ifr->ifr_data);
-
-       return -EOPNOTSUPP;
-}
-
 static int brcmf_netdev_stop(struct net_device *ndev)
 {
        struct brcmf_if *ifp = netdev_priv(ndev);
@@ -769,7 +629,6 @@ static int brcmf_netdev_open(struct net_device *ndev)
        struct brcmf_pub *drvr = ifp->drvr;
        struct brcmf_bus *bus_if = drvr->bus_if;
        u32 toe_ol;
-       s32 ret = 0;
 
        brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
 
@@ -788,21 +647,20 @@ static int brcmf_netdev_open(struct net_device *ndev)
        else
                ndev->features &= ~NETIF_F_IP_CSUM;
 
-       /* Allow transmit calls */
-       netif_start_queue(ndev);
        if (brcmf_cfg80211_up(ndev)) {
                brcmf_err("failed to bring up cfg80211\n");
-               return -1;
+               return -EIO;
        }
 
-       return ret;
+       /* Allow transmit calls */
+       netif_start_queue(ndev);
+       return 0;
 }
 
 static const struct net_device_ops brcmf_netdev_ops_pri = {
        .ndo_open = brcmf_netdev_open,
        .ndo_stop = brcmf_netdev_stop,
        .ndo_get_stats = brcmf_netdev_get_stats,
-       .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
        .ndo_start_xmit = brcmf_netdev_start_xmit,
        .ndo_set_mac_address = brcmf_netdev_set_mac_address,
        .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
@@ -868,13 +726,6 @@ static int brcmf_net_p2p_stop(struct net_device *ndev)
        return brcmf_cfg80211_down(ndev);
 }
 
-static int brcmf_net_p2p_do_ioctl(struct net_device *ndev,
-                                 struct ifreq *ifr, int cmd)
-{
-       brcmf_dbg(TRACE, "Enter\n");
-       return 0;
-}
-
 static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
                                            struct net_device *ndev)
 {
@@ -887,7 +738,6 @@ static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
 static const struct net_device_ops brcmf_netdev_ops_p2p = {
        .ndo_open = brcmf_net_p2p_open,
        .ndo_stop = brcmf_net_p2p_stop,
-       .ndo_do_ioctl = brcmf_net_p2p_do_ioctl,
        .ndo_start_xmit = brcmf_net_p2p_start_xmit
 };
 
@@ -1016,7 +866,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
        }
 }
 
-int brcmf_attach(uint bus_hdrlen, struct device *dev)
+int brcmf_attach(struct device *dev)
 {
        struct brcmf_pub *drvr = NULL;
        int ret = 0;
@@ -1031,7 +881,7 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
        mutex_init(&drvr->proto_block);
 
        /* Link to bus module */
-       drvr->hdrlen = bus_hdrlen;
+       drvr->hdrlen = 0;
        drvr->bus_if = dev_get_drvdata(dev);
        drvr->bus_if->drvr = drvr;
 
@@ -1048,8 +898,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
        /* attach firmware event handler */
        brcmf_fweh_attach(drvr);
 
-       INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
-
        return ret;
 
 fail:
@@ -1138,14 +986,21 @@ fail:
        return 0;
 }
 
+void brcmf_bus_add_txhdrlen(struct device *dev, uint len)
+{
+       struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+       struct brcmf_pub *drvr = bus_if->drvr;
+
+       if (drvr) {
+               drvr->hdrlen += len;
+       }
+}
+
 static void brcmf_bus_detach(struct brcmf_pub *drvr)
 {
        brcmf_dbg(TRACE, "Enter\n");
 
        if (drvr) {
-               /* Stop the protocol module */
-               brcmf_proto_stop(drvr);
-
                /* Stop the bus module */
                brcmf_bus_stop(drvr->bus_if);
        }
@@ -1186,8 +1041,7 @@ void brcmf_detach(struct device *dev)
 
        brcmf_bus_detach(drvr);
 
-       if (drvr->prot)
-               brcmf_proto_detach(drvr);
+       brcmf_proto_detach(drvr);
 
        brcmf_fws_deinit(drvr);
 
@@ -1196,6 +1050,14 @@ void brcmf_detach(struct device *dev)
        kfree(drvr);
 }
 
+s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
+{
+       struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+       struct brcmf_if *ifp = bus_if->drvr->iflist[0];
+
+       return brcmf_fil_iovar_data_set(ifp, name, data, len);
+}
+
 static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
 {
        return atomic_read(&ifp->pend_8021x_cnt);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
deleted file mode 100644 (file)
index 53c6e71..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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.
- */
-
-#ifndef _BRCMF_PROTO_H_
-#define _BRCMF_PROTO_H_
-
-/*
- * Exported from the brcmf protocol module (brcmf_cdc)
- */
-
-/* Linkage, sets prot link and updates hdrlen in pub */
-int brcmf_proto_attach(struct brcmf_pub *drvr);
-
-/* Unlink, frees allocated protocol memory (including brcmf_proto) */
-void brcmf_proto_detach(struct brcmf_pub *drvr);
-
-/* Stop protocol: sync w/dongle state. */
-void brcmf_proto_stop(struct brcmf_pub *drvr);
-
-/* Add any protocol-specific data header.
- * Caller must reserve prot_hdrlen prepend space.
- */
-void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset,
-                        struct sk_buff *txp);
-
-/* Sets dongle media info (drv_version, mac address). */
-int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
-
-#endif                         /* _BRCMF_PROTO_H_ */
index b02953c4ade721235fbe0e4ed662aaa422ab21f7..0f95f3e79c10f6e04f8a5735a102e3059739e4f8 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/debugfs.h>
 #include <linux/vmalloc.h>
 #include <linux/platform_data/brcmfmac-sdio.h>
+#include <linux/moduleparam.h>
 #include <asm/unaligned.h>
 #include <defs.h>
 #include <brcmu_wifi.h>
@@ -110,6 +111,8 @@ struct rte_console {
 #define BRCMF_TXBOUND  20      /* Default for max tx frames in
                                 one scheduling */
 
+#define BRCMF_DEFAULT_TXGLOM_SIZE      32  /* max tx frames in glom chain */
+
 #define BRCMF_TXMINMAX 1       /* Max tx frames if rx still pending */
 
 #define MEMBLOCK       2048    /* Block size used for downloading
@@ -360,6 +363,8 @@ struct brcmf_sdio_hdrinfo {
        u16 len_left;
        u16 len_nxtfrm;
        u8 dat_offset;
+       bool lastfrm;
+       u16 tail_pad;
 };
 
 /* misc chip info needed by some of the routines */
@@ -384,7 +389,7 @@ struct brcmf_sdio {
        u8 tx_seq;              /* Transmit sequence number (next) */
        u8 tx_max;              /* Maximum transmit sequence allowed */
 
-       u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN];
+       u8 *hdrbuf;             /* buffer for handling rx frame */
        u8 *rxhdr;              /* Header of current rx frame (in hdrbuf) */
        u8 rx_seq;              /* Receive sequence number (expected) */
        struct brcmf_sdio_hdrinfo cur_read;
@@ -455,6 +460,10 @@ struct brcmf_sdio {
        bool sleeping; /* SDIO bus sleeping */
 
        u8 tx_hdrlen;           /* sdio bus header length for tx packet */
+       bool txglom;            /* host tx glomming enable flag */
+       struct sk_buff *txglom_sgpad;   /* scatter-gather padding buffer */
+       u16 head_align;         /* buffer pointer alignment */
+       u16 sgentry_align;      /* scatter-gather buffer alignment */
 };
 
 /* clkstate */
@@ -479,6 +488,10 @@ static const uint max_roundup = 512;
 
 #define ALIGNMENT  4
 
+static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
+module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0);
+MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
+
 enum brcmf_sdio_frmtype {
        BRCMF_SDIO_FT_NORMAL,
        BRCMF_SDIO_FT_SUPER,
@@ -499,6 +512,8 @@ enum brcmf_sdio_frmtype {
 #define BCM4334_NVRAM_NAME             "brcm/brcmfmac4334-sdio.txt"
 #define BCM4335_FIRMWARE_NAME          "brcm/brcmfmac4335-sdio.bin"
 #define BCM4335_NVRAM_NAME             "brcm/brcmfmac4335-sdio.txt"
+#define BCM4339_FIRMWARE_NAME          "brcm/brcmfmac4339-sdio.bin"
+#define BCM4339_NVRAM_NAME             "brcm/brcmfmac4339-sdio.txt"
 
 MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME);
 MODULE_FIRMWARE(BCM43143_NVRAM_NAME);
@@ -514,6 +529,8 @@ MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME);
 MODULE_FIRMWARE(BCM4334_NVRAM_NAME);
 MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME);
 MODULE_FIRMWARE(BCM4335_NVRAM_NAME);
+MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
+MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
 
 struct brcmf_firmware_names {
        u32 chipid;
@@ -537,7 +554,8 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = {
        { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
        { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
        { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
-       { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }
+       { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
+       { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }
 };
 
 
@@ -1097,10 +1115,18 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
  * host and WiFi dongle which contains information needed for SDIO core and
  * firmware
  *
- * It consists of 2 parts: hw header and software header
+ * It consists of 3 parts: hardware header, hardware extension header and
+ * software header
  * hardware header (frame tag) - 4 bytes
  * Byte 0~1: Frame length
  * Byte 2~3: Checksum, bit-wise inverse of frame length
+ * hardware extension header - 8 bytes
+ * Tx glom mode only, N/A for Rx or normal Tx
+ * Byte 0~1: Packet length excluding hw frame tag
+ * Byte 2: Reserved
+ * Byte 3: Frame flags, bit 0: last frame indication
+ * Byte 4~5: Reserved
+ * Byte 6~7: Tail padding length
  * software header - 8 bytes
  * Byte 0: Rx/Tx sequence number
  * Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag
@@ -1111,6 +1137,7 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
  * Byte 6~7: Reserved
  */
 #define SDPCM_HWHDR_LEN                        4
+#define SDPCM_HWEXT_LEN                        8
 #define SDPCM_SWHDR_LEN                        8
 #define SDPCM_HDRLEN                   (SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN)
 /* software header */
@@ -1147,7 +1174,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
        u8 rx_seq, fc, tx_seq_max;
        u32 swheader;
 
-       trace_brcmf_sdpcm_hdr(false, header);
+       trace_brcmf_sdpcm_hdr(SDPCM_RX, header);
 
        /* hw header */
        len = get_unaligned_le16(header);
@@ -1260,25 +1287,34 @@ static inline void brcmf_sdio_update_hwhdr(u8 *header, u16 frm_length)
 static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header,
                              struct brcmf_sdio_hdrinfo *hd_info)
 {
-       u32 sw_header;
+       u32 hdrval;
+       u8 hdr_offset;
 
        brcmf_sdio_update_hwhdr(header, hd_info->len);
-
-       sw_header = bus->tx_seq;
-       sw_header |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) &
-                    SDPCM_CHANNEL_MASK;
-       sw_header |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) &
-                    SDPCM_DOFFSET_MASK;
-       *(((__le32 *)header) + 1) = cpu_to_le32(sw_header);
-       *(((__le32 *)header) + 2) = 0;
-       trace_brcmf_sdpcm_hdr(true, header);
+       hdr_offset = SDPCM_HWHDR_LEN;
+
+       if (bus->txglom) {
+               hdrval = (hd_info->len - hdr_offset) | (hd_info->lastfrm << 24);
+               *((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval);
+               hdrval = (u16)hd_info->tail_pad << 16;
+               *(((__le32 *)(header + hdr_offset)) + 1) = cpu_to_le32(hdrval);
+               hdr_offset += SDPCM_HWEXT_LEN;
+       }
+
+       hdrval = hd_info->seq_num;
+       hdrval |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) &
+                 SDPCM_CHANNEL_MASK;
+       hdrval |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) &
+                 SDPCM_DOFFSET_MASK;
+       *((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval);
+       *(((__le32 *)(header + hdr_offset)) + 1) = 0;
+       trace_brcmf_sdpcm_hdr(SDPCM_TX + !!(bus->txglom), header);
 }
 
 static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
 {
        u16 dlen, totlen;
        u8 *dptr, num = 0;
-       u32 align = 0;
        u16 sublen;
        struct sk_buff *pfirst, *pnext;
 
@@ -1293,11 +1329,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
        brcmf_dbg(SDIO, "start: glomd %p glom %p\n",
                  bus->glomd, skb_peek(&bus->glom));
 
-       if (bus->sdiodev->pdata)
-               align = bus->sdiodev->pdata->sd_sgentry_align;
-       if (align < 4)
-               align = 4;
-
        /* If there's a descriptor, generate the packet chain */
        if (bus->glomd) {
                pfirst = pnext = NULL;
@@ -1321,9 +1352,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
                                pnext = NULL;
                                break;
                        }
-                       if (sublen % align) {
+                       if (sublen % bus->sgentry_align) {
                                brcmf_err("sublen %d not multiple of %d\n",
-                                         sublen, align);
+                                         sublen, bus->sgentry_align);
                        }
                        totlen += sublen;
 
@@ -1336,7 +1367,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
                        }
 
                        /* Allocate/chain packet for next subframe */
-                       pnext = brcmu_pkt_buf_get_skb(sublen + align);
+                       pnext = brcmu_pkt_buf_get_skb(sublen + bus->sgentry_align);
                        if (pnext == NULL) {
                                brcmf_err("bcm_pkt_buf_get_skb failed, num %d len %d\n",
                                          num, sublen);
@@ -1345,7 +1376,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
                        skb_queue_tail(&bus->glom, pnext);
 
                        /* Adhere to start alignment requirements */
-                       pkt_align(pnext, sublen, align);
+                       pkt_align(pnext, sublen, bus->sgentry_align);
                }
 
                /* If all allocations succeeded, save packet chain
@@ -1549,9 +1580,9 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
                goto done;
 
        rbuf = bus->rxbuf;
-       pad = ((unsigned long)rbuf % BRCMF_SDALIGN);
+       pad = ((unsigned long)rbuf % bus->head_align);
        if (pad)
-               rbuf += (BRCMF_SDALIGN - pad);
+               rbuf += (bus->head_align - pad);
 
        /* Copy the already-read portion over */
        memcpy(buf, hdr, BRCMF_FIRSTREAD);
@@ -1565,14 +1596,10 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
                if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
                    ((len + pad) < bus->sdiodev->bus_if->maxctl))
                        rdlen += pad;
-       } else if (rdlen % BRCMF_SDALIGN) {
-               rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
+       } else if (rdlen % bus->head_align) {
+               rdlen += bus->head_align - (rdlen % bus->head_align);
        }
 
-       /* Satisfy length-alignment requirements */
-       if (rdlen & (ALIGNMENT - 1))
-               rdlen = roundup(rdlen, ALIGNMENT);
-
        /* Drop if the read is too big or it exceeds our maximum */
        if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
                brcmf_err("%d-byte control read exceeds %d-byte buffer\n",
@@ -1637,8 +1664,8 @@ static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen)
                if (*pad <= bus->roundup && *pad < bus->blocksize &&
                    *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ)
                        *rdlen += *pad;
-       } else if (*rdlen % BRCMF_SDALIGN) {
-               *rdlen += BRCMF_SDALIGN - (*rdlen % BRCMF_SDALIGN);
+       } else if (*rdlen % bus->head_align) {
+               *rdlen += bus->head_align - (*rdlen % bus->head_align);
        }
 }
 
@@ -1726,7 +1753,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
                brcmf_pad(bus, &pad, &rd->len_left);
 
                pkt = brcmu_pkt_buf_get_skb(rd->len_left + head_read +
-                                           BRCMF_SDALIGN);
+                                           bus->head_align);
                if (!pkt) {
                        /* Give up on data, request rtx of events */
                        brcmf_err("brcmu_pkt_buf_get_skb failed\n");
@@ -1736,7 +1763,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
                        continue;
                }
                skb_pull(pkt, head_read);
-               pkt_align(pkt, rd->len_left, BRCMF_SDALIGN);
+               pkt_align(pkt, rd->len_left, bus->head_align);
 
                ret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
                                              SDIO_FUNC_2, F2SYNC, pkt);
@@ -1871,6 +1898,29 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
        return;
 }
 
+static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt)
+{
+       u16 head_pad;
+       u8 *dat_buf;
+
+       dat_buf = (u8 *)(pkt->data);
+
+       /* Check head padding */
+       head_pad = ((unsigned long)dat_buf % bus->head_align);
+       if (head_pad) {
+               if (skb_headroom(pkt) < head_pad) {
+                       bus->sdiodev->bus_if->tx_realloc++;
+                       head_pad = 0;
+                       if (skb_cow(pkt, head_pad))
+                               return -ENOMEM;
+               }
+               skb_push(pkt, head_pad);
+               dat_buf = (u8 *)(pkt->data);
+               memset(dat_buf, 0, head_pad + bus->tx_hdrlen);
+       }
+       return head_pad;
+}
+
 /**
  * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for
  * bus layer usage.
@@ -1880,32 +1930,40 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
 /* bit mask of data length chopped from the previous packet */
 #define ALIGN_SKB_CHOP_LEN_MASK        0x7fff
 
-static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev,
+static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus,
                                    struct sk_buff_head *pktq,
-                                   struct sk_buff *pkt, uint chan)
+                                   struct sk_buff *pkt, u16 total_len)
 {
+       struct brcmf_sdio_dev *sdiodev;
        struct sk_buff *pkt_pad;
-       u16 tail_pad, tail_chop, sg_align;
+       u16 tail_pad, tail_chop, chain_pad;
        unsigned int blksize;
-       u8 *dat_buf;
-       int ntail;
+       bool lastfrm;
+       int ntail, ret;
 
+       sdiodev = bus->sdiodev;
        blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize;
-       sg_align = 4;
-       if (sdiodev->pdata && sdiodev->pdata->sd_sgentry_align > 4)
-               sg_align = sdiodev->pdata->sd_sgentry_align;
        /* sg entry alignment should be a divisor of block size */
-       WARN_ON(blksize % sg_align);
+       WARN_ON(blksize % bus->sgentry_align);
 
        /* Check tail padding */
-       pkt_pad = NULL;
-       tail_chop = pkt->len % sg_align;
-       tail_pad = sg_align - tail_chop;
-       tail_pad += blksize - (pkt->len + tail_pad) % blksize;
+       lastfrm = skb_queue_is_last(pktq, pkt);
+       tail_pad = 0;
+       tail_chop = pkt->len % bus->sgentry_align;
+       if (tail_chop)
+               tail_pad = bus->sgentry_align - tail_chop;
+       chain_pad = (total_len + tail_pad) % blksize;
+       if (lastfrm && chain_pad)
+               tail_pad += blksize - chain_pad;
        if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) {
-               pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop);
+               pkt_pad = bus->txglom_sgpad;
+               if (pkt_pad == NULL)
+                         brcmu_pkt_buf_get_skb(tail_pad + tail_chop);
                if (pkt_pad == NULL)
                        return -ENOMEM;
+               ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad);
+               if (unlikely(ret < 0))
+                       return ret;
                memcpy(pkt_pad->data,
                       pkt->data + pkt->len - tail_chop,
                       tail_chop);
@@ -1920,14 +1978,10 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev,
                                return -ENOMEM;
                if (skb_linearize(pkt))
                        return -ENOMEM;
-               dat_buf = (u8 *)(pkt->data);
                __skb_put(pkt, tail_pad);
        }
 
-       if (pkt_pad)
-               return pkt->len + tail_chop;
-       else
-               return pkt->len - tail_pad;
+       return tail_pad;
 }
 
 /**
@@ -1946,58 +2000,66 @@ static int
 brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
                      uint chan)
 {
-       u16 head_pad, head_align;
+       u16 head_pad, total_len;
        struct sk_buff *pkt_next;
-       u8 *dat_buf;
-       int err;
+       u8 txseq;
+       int ret;
        struct brcmf_sdio_hdrinfo hd_info = {0};
 
-       /* SDIO ADMA requires at least 32 bit alignment */
-       head_align = 4;
-       if (bus->sdiodev->pdata && bus->sdiodev->pdata->sd_head_align > 4)
-               head_align = bus->sdiodev->pdata->sd_head_align;
+       txseq = bus->tx_seq;
+       total_len = 0;
+       skb_queue_walk(pktq, pkt_next) {
+               /* alignment packet inserted in previous
+                * loop cycle can be skipped as it is
+                * already properly aligned and does not
+                * need an sdpcm header.
+                */
+               if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
+                       continue;
 
-       pkt_next = pktq->next;
-       dat_buf = (u8 *)(pkt_next->data);
+               /* align packet data pointer */
+               ret = brcmf_sdio_txpkt_hdalign(bus, pkt_next);
+               if (ret < 0)
+                       return ret;
+               head_pad = (u16)ret;
+               if (head_pad)
+                       memset(pkt_next->data, 0, head_pad + bus->tx_hdrlen);
 
-       /* Check head padding */
-       head_pad = ((unsigned long)dat_buf % head_align);
-       if (head_pad) {
-               if (skb_headroom(pkt_next) < head_pad) {
-                       bus->sdiodev->bus_if->tx_realloc++;
-                       head_pad = 0;
-                       if (skb_cow(pkt_next, head_pad))
-                               return -ENOMEM;
-               }
-               skb_push(pkt_next, head_pad);
-               dat_buf = (u8 *)(pkt_next->data);
-               memset(dat_buf, 0, head_pad + bus->tx_hdrlen);
-       }
+               total_len += pkt_next->len;
 
-       if (bus->sdiodev->sg_support && pktq->qlen > 1) {
-               err = brcmf_sdio_txpkt_prep_sg(bus->sdiodev, pktq,
-                                              pkt_next, chan);
-               if (err < 0)
-                       return err;
-               hd_info.len = (u16)err;
-       } else {
                hd_info.len = pkt_next->len;
-       }
-
-       hd_info.channel = chan;
-       hd_info.dat_offset = head_pad + bus->tx_hdrlen;
-
-       /* Now fill the header */
-       brcmf_sdio_hdpack(bus, dat_buf, &hd_info);
-
-       if (BRCMF_BYTES_ON() &&
-           ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
-            (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
-               brcmf_dbg_hex_dump(true, pkt_next, hd_info.len, "Tx Frame:\n");
-       else if (BRCMF_HDRS_ON())
-               brcmf_dbg_hex_dump(true, pkt_next, head_pad + bus->tx_hdrlen,
-                                  "Tx Header:\n");
+               hd_info.lastfrm = skb_queue_is_last(pktq, pkt_next);
+               if (bus->txglom && pktq->qlen > 1) {
+                       ret = brcmf_sdio_txpkt_prep_sg(bus, pktq,
+                                                      pkt_next, total_len);
+                       if (ret < 0)
+                               return ret;
+                       hd_info.tail_pad = (u16)ret;
+                       total_len += (u16)ret;
+               }
 
+               hd_info.channel = chan;
+               hd_info.dat_offset = head_pad + bus->tx_hdrlen;
+               hd_info.seq_num = txseq++;
+
+               /* Now fill the header */
+               brcmf_sdio_hdpack(bus, pkt_next->data, &hd_info);
+
+               if (BRCMF_BYTES_ON() &&
+                   ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
+                    (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
+                       brcmf_dbg_hex_dump(true, pkt_next, hd_info.len,
+                                          "Tx Frame:\n");
+               else if (BRCMF_HDRS_ON())
+                       brcmf_dbg_hex_dump(true, pkt_next,
+                                          head_pad + bus->tx_hdrlen,
+                                          "Tx Header:\n");
+       }
+       /* Hardware length tag of the first packet should be total
+        * length of the chain (including padding)
+        */
+       if (bus->txglom)
+               brcmf_sdio_update_hwhdr(pktq->next->data, total_len);
        return 0;
 }
 
@@ -2015,6 +2077,7 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
 {
        u8 *hdr;
        u32 dat_offset;
+       u16 tail_pad;
        u32 dummy_flags, chop_len;
        struct sk_buff *pkt_next, *tmp, *pkt_prev;
 
@@ -2024,42 +2087,42 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
                        chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
                        if (chop_len) {
                                pkt_prev = pkt_next->prev;
-                               memcpy(pkt_prev->data + pkt_prev->len,
-                                      pkt_next->data, chop_len);
                                skb_put(pkt_prev, chop_len);
                        }
                        __skb_unlink(pkt_next, pktq);
                        brcmu_pkt_buf_free_skb(pkt_next);
                } else {
-                       hdr = pkt_next->data + SDPCM_HWHDR_LEN;
+                       hdr = pkt_next->data + bus->tx_hdrlen - SDPCM_SWHDR_LEN;
                        dat_offset = le32_to_cpu(*(__le32 *)hdr);
                        dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >>
                                     SDPCM_DOFFSET_SHIFT;
                        skb_pull(pkt_next, dat_offset);
+                       if (bus->txglom) {
+                               tail_pad = le16_to_cpu(*(__le16 *)(hdr - 2));
+                               skb_trim(pkt_next, pkt_next->len - tail_pad);
+                       }
                }
        }
 }
 
 /* Writes a HW/SW header into the packet and sends it. */
 /* Assumes: (a) header space already there, (b) caller holds lock */
-static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
+static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
                              uint chan)
 {
        int ret;
        int i;
-       struct sk_buff_head localq;
+       struct sk_buff *pkt_next, *tmp;
 
        brcmf_dbg(TRACE, "Enter\n");
 
-       __skb_queue_head_init(&localq);
-       __skb_queue_tail(&localq, pkt);
-       ret = brcmf_sdio_txpkt_prep(bus, &localq, chan);
+       ret = brcmf_sdio_txpkt_prep(bus, pktq, chan);
        if (ret)
                goto done;
 
        sdio_claim_host(bus->sdiodev->func[1]);
        ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
-                                   SDIO_FUNC_2, F2SYNC, &localq);
+                                   SDIO_FUNC_2, F2SYNC, pktq);
        bus->sdcnt.f2txdata++;
 
        if (ret < 0) {
@@ -2083,42 +2146,56 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
                        if ((hi == 0) && (lo == 0))
                                break;
                }
-
        }
        sdio_release_host(bus->sdiodev->func[1]);
-       if (ret == 0)
-               bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
 
 done:
-       brcmf_sdio_txpkt_postp(bus, &localq);
-       __skb_dequeue_tail(&localq);
-       brcmf_txcomplete(bus->sdiodev->dev, pkt, ret == 0);
+       brcmf_sdio_txpkt_postp(bus, pktq);
+       if (ret == 0)
+               bus->tx_seq = (bus->tx_seq + pktq->qlen) % SDPCM_SEQ_WRAP;
+       skb_queue_walk_safe(pktq, pkt_next, tmp) {
+               __skb_unlink(pkt_next, pktq);
+               brcmf_txcomplete(bus->sdiodev->dev, pkt_next, ret == 0);
+       }
        return ret;
 }
 
 static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
 {
        struct sk_buff *pkt;
+       struct sk_buff_head pktq;
        u32 intstatus = 0;
-       int ret = 0, prec_out;
+       int ret = 0, prec_out, i;
        uint cnt = 0;
-       u8 tx_prec_map;
+       u8 tx_prec_map, pkt_num;
 
        brcmf_dbg(TRACE, "Enter\n");
 
        tx_prec_map = ~bus->flowcontrol;
 
        /* Send frames until the limit or some other event */
-       for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) {
+       for (cnt = 0; (cnt < maxframes) && data_ok(bus);) {
+               pkt_num = 1;
+               __skb_queue_head_init(&pktq);
+               if (bus->txglom)
+                       pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
+                                       brcmf_sdio_txglomsz);
+               pkt_num = min_t(u32, pkt_num,
+                               brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
                spin_lock_bh(&bus->txqlock);
-               pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
-               if (pkt == NULL) {
-                       spin_unlock_bh(&bus->txqlock);
-                       break;
+               for (i = 0; i < pkt_num; i++) {
+                       pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map,
+                                             &prec_out);
+                       if (pkt == NULL)
+                               break;
+                       __skb_queue_tail(&pktq, pkt);
                }
                spin_unlock_bh(&bus->txqlock);
+               if (i == 0)
+                       break;
 
-               ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL);
+               ret = brcmf_sdbrcm_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL);
+               cnt += i;
 
                /* In poll mode, need to check for other events */
                if (!bus->intr && cnt) {
@@ -2665,7 +2742,7 @@ static int
 brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
 {
        u8 *frame;
-       u16 len;
+       u16 len, pad;
        uint retries = 0;
        u8 doff = 0;
        int ret = -1;
@@ -2681,28 +2758,26 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
        len = (msglen += bus->tx_hdrlen);
 
        /* Add alignment padding (optional for ctl frames) */
-       doff = ((unsigned long)frame % BRCMF_SDALIGN);
+       doff = ((unsigned long)frame % bus->head_align);
        if (doff) {
                frame -= doff;
                len += doff;
                msglen += doff;
                memset(frame, 0, doff + bus->tx_hdrlen);
        }
-       /* precondition: doff < BRCMF_SDALIGN */
+       /* precondition: doff < bus->head_align */
        doff += bus->tx_hdrlen;
 
        /* Round send length to next SDIO block */
+       pad = 0;
        if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
-               u16 pad = bus->blocksize - (len % bus->blocksize);
-               if ((pad <= bus->roundup) && (pad < bus->blocksize))
-                       len += pad;
-       } else if (len % BRCMF_SDALIGN) {
-               len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
+               pad = bus->blocksize - (len % bus->blocksize);
+               if ((pad > bus->roundup) || (pad >= bus->blocksize))
+                       pad = 0;
+       } else if (len % bus->head_align) {
+               pad = bus->head_align - (len % bus->head_align);
        }
-
-       /* Satisfy length-alignment requirements */
-       if (len & (ALIGNMENT - 1))
-               len = roundup(len, ALIGNMENT);
+       len += pad;
 
        /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
 
@@ -2714,8 +2789,14 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
        hd_info.len = (u16)msglen;
        hd_info.channel = SDPCM_CONTROL_CHANNEL;
        hd_info.dat_offset = doff;
+       hd_info.seq_num = bus->tx_seq;
+       hd_info.lastfrm = true;
+       hd_info.tail_pad = pad;
        brcmf_sdio_hdpack(bus, frame, &hd_info);
 
+       if (bus->txglom)
+               brcmf_sdio_update_hwhdr(frame, len);
+
        if (!data_ok(bus)) {
                brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
                          bus->tx_max, bus->tx_seq);
@@ -3425,6 +3506,65 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
        return ret;
 }
 
+static int brcmf_sdbrcm_bus_preinit(struct device *dev)
+{
+       struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+       struct brcmf_sdio *bus = sdiodev->bus;
+       uint pad_size;
+       u32 value;
+       u8 idx;
+       int err;
+
+       /* the commands below use the terms tx and rx from
+        * a device perspective, ie. bus:txglom affects the
+        * bus transfers from device to host.
+        */
+       idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
+       if (bus->ci->c_inf[idx].rev < 12) {
+               /* for sdio core rev < 12, disable txgloming */
+               value = 0;
+               err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
+                                          sizeof(u32));
+       } else {
+               /* otherwise, set txglomalign */
+               value = 4;
+               if (sdiodev->pdata)
+                       value = sdiodev->pdata->sd_sgentry_align;
+               /* SDIO ADMA requires at least 32 bit alignment */
+               value = max_t(u32, value, 4);
+               err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
+                                          sizeof(u32));
+       }
+
+       if (err < 0)
+               goto done;
+
+       bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
+       if (sdiodev->sg_support) {
+               bus->txglom = false;
+               value = 1;
+               pad_size = bus->sdiodev->func[2]->cur_blksize << 1;
+               bus->txglom_sgpad = brcmu_pkt_buf_get_skb(pad_size);
+               if (!bus->txglom_sgpad)
+                       brcmf_err("allocating txglom padding skb failed, reduced performance\n");
+
+               err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom",
+                                          &value, sizeof(u32));
+               if (err < 0) {
+                       /* bus:rxglom is allowed to fail */
+                       err = 0;
+               } else {
+                       bus->txglom = true;
+                       bus->tx_hdrlen += SDPCM_HWEXT_LEN;
+               }
+       }
+       brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen);
+
+done:
+       return err;
+}
+
 static int brcmf_sdbrcm_bus_init(struct device *dev)
 {
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -3673,7 +3813,7 @@ static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus)
        if (bus->sdiodev->bus_if->maxctl) {
                bus->rxblen =
                    roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN),
-                           ALIGNMENT) + BRCMF_SDALIGN;
+                           ALIGNMENT) + bus->head_align;
                bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
                if (!(bus->rxbuf))
                        return false;
@@ -3774,9 +3914,13 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
 
        brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
 
+       /* allocate header buffer */
+       bus->hdrbuf = kzalloc(MAX_HDR_READ + bus->head_align, GFP_KERNEL);
+       if (!bus->hdrbuf)
+               return false;
        /* Locate an appropriately-aligned portion of hdrbuf */
        bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
-                                   BRCMF_SDALIGN);
+                                   bus->head_align);
 
        /* Set the poll and/or interrupt flags */
        bus->intr = true;
@@ -3895,8 +4039,9 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
                        brcmf_sdbrcm_release_dongle(bus);
                }
 
+               brcmu_pkt_buf_free_skb(bus->txglom_sgpad);
                brcmf_sdbrcm_release_malloc(bus);
-
+               kfree(bus->hdrbuf);
                kfree(bus);
        }
 
@@ -3905,6 +4050,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
 
 static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
        .stop = brcmf_sdbrcm_bus_stop,
+       .preinit = brcmf_sdbrcm_bus_preinit,
        .init = brcmf_sdbrcm_bus_init,
        .txdata = brcmf_sdbrcm_bus_txdata,
        .txctl = brcmf_sdbrcm_bus_txctl,
@@ -3916,10 +4062,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
 {
        int ret;
        struct brcmf_sdio *bus;
-       struct brcmf_bus_dcmd *dlst;
-       u32 dngl_txglom;
-       u32 txglomalign = 0;
-       u8 idx;
 
        brcmf_dbg(TRACE, "Enter\n");
 
@@ -3939,6 +4081,18 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
        bus->txminmax = BRCMF_TXMINMAX;
        bus->tx_seq = SDPCM_SEQ_WRAP - 1;
 
+       /* platform specific configuration:
+        *   alignments must be at least 4 bytes for ADMA
+         */
+       bus->head_align = ALIGNMENT;
+       bus->sgentry_align = ALIGNMENT;
+       if (sdiodev->pdata) {
+               if (sdiodev->pdata->sd_head_align > ALIGNMENT)
+                       bus->head_align = sdiodev->pdata->sd_head_align;
+               if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT)
+                       bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
+       }
+
        INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
        bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq");
        if (bus->brcmf_wq == NULL) {
@@ -3983,7 +4137,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
        bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
 
        /* Attach to the common layer, reserve hdr space */
-       ret = brcmf_attach(bus->tx_hdrlen, bus->sdiodev->dev);
+       ret = brcmf_attach(bus->sdiodev->dev);
        if (ret != 0) {
                brcmf_err("brcmf_attach failed\n");
                goto fail;
@@ -4003,30 +4157,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
        brcmf_sdio_debugfs_create(bus);
        brcmf_dbg(INFO, "completed!!\n");
 
-       /* sdio bus core specific dcmd */
-       idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
-       dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL);
-       if (dlst) {
-               if (bus->ci->c_inf[idx].rev < 12) {
-                       /* for sdio core rev < 12, disable txgloming */
-                       dngl_txglom = 0;
-                       dlst->name = "bus:txglom";
-                       dlst->param = (char *)&dngl_txglom;
-                       dlst->param_len = sizeof(u32);
-               } else {
-                       /* otherwise, set txglomalign */
-                       if (sdiodev->pdata)
-                               txglomalign = sdiodev->pdata->sd_sgentry_align;
-                       /* SDIO ADMA requires at least 32 bit alignment */
-                       if (txglomalign < 4)
-                               txglomalign = 4;
-                       dlst->name = "bus:txglomalign";
-                       dlst->param = (char *)&txglomalign;
-                       dlst->param_len = sizeof(u32);
-               }
-               list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list);
-       }
-
        /* if firmware path present try to download and bring up bus */
        ret = brcmf_bus_start(bus->sdiodev->dev);
        if (ret != 0) {
index 14bc24dc5baeb1f8272b4da0660d893c4bfc9b48..51b53a73d07464c0bb9b8b5a6f551e20314c37ce 100644 (file)
@@ -122,6 +122,52 @@ enum brcmf_fweh_event_code {
 #define BRCMF_EVENT_MSG_FLUSHTXQ       0x02
 #define BRCMF_EVENT_MSG_GROUP          0x04
 
+/* status field values in struct brcmf_event_msg */
+#define BRCMF_E_STATUS_SUCCESS                 0
+#define BRCMF_E_STATUS_FAIL                    1
+#define BRCMF_E_STATUS_TIMEOUT                 2
+#define BRCMF_E_STATUS_NO_NETWORKS             3
+#define BRCMF_E_STATUS_ABORT                   4
+#define BRCMF_E_STATUS_NO_ACK                  5
+#define BRCMF_E_STATUS_UNSOLICITED             6
+#define BRCMF_E_STATUS_ATTEMPT                 7
+#define BRCMF_E_STATUS_PARTIAL                 8
+#define BRCMF_E_STATUS_NEWSCAN                 9
+#define BRCMF_E_STATUS_NEWASSOC                        10
+#define BRCMF_E_STATUS_11HQUIET                        11
+#define BRCMF_E_STATUS_SUPPRESS                        12
+#define BRCMF_E_STATUS_NOCHANS                 13
+#define BRCMF_E_STATUS_CS_ABORT                        15
+#define BRCMF_E_STATUS_ERROR                   16
+
+/* reason field values in struct brcmf_event_msg */
+#define BRCMF_E_REASON_INITIAL_ASSOC           0
+#define BRCMF_E_REASON_LOW_RSSI                        1
+#define BRCMF_E_REASON_DEAUTH                  2
+#define BRCMF_E_REASON_DISASSOC                        3
+#define BRCMF_E_REASON_BCNS_LOST               4
+#define BRCMF_E_REASON_MINTXRATE               9
+#define BRCMF_E_REASON_TXFAIL                  10
+
+#define BRCMF_E_REASON_LINK_BSSCFG_DIS         4
+#define BRCMF_E_REASON_FAST_ROAM_FAILED                5
+#define BRCMF_E_REASON_DIRECTED_ROAM           6
+#define BRCMF_E_REASON_TSPEC_REJECTED          7
+#define BRCMF_E_REASON_BETTER_AP               8
+
+/* action field values for brcmf_ifevent */
+#define BRCMF_E_IF_ADD                         1
+#define BRCMF_E_IF_DEL                         2
+#define BRCMF_E_IF_CHANGE                      3
+
+/* flag field values for brcmf_ifevent */
+#define BRCMF_E_IF_FLAG_NOIF                   1
+
+/* role field values for brcmf_ifevent */
+#define BRCMF_E_IF_ROLE_STA                    0
+#define BRCMF_E_IF_ROLE_AP                     1
+#define BRCMF_E_IF_ROLE_WDS                    2
+
 /**
  * definitions for event packet validation.
  */
@@ -160,6 +206,14 @@ struct brcmf_event_msg {
        u8 bsscfgidx;
 };
 
+struct brcmf_if_event {
+       u8 ifidx;
+       u8 action;
+       u8 flags;
+       u8 bssidx;
+       u8 role;
+};
+
 typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
                                    const struct brcmf_event_msg *evtmsg,
                                    void *data);
index 04f395930d86742372585ff42b3ce3837f0d606d..b72d3395499a3c1e713af54a4379f86e93ca407a 100644 (file)
@@ -27,6 +27,7 @@
 #include "dhd_dbg.h"
 #include "tracepoint.h"
 #include "fwil.h"
+#include "proto.h"
 
 
 #define MAX_HEX_DUMP_LEN       64
@@ -46,11 +47,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
        if (data != NULL)
                len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
        if (set)
-               err = brcmf_proto_cdc_set_dcmd(drvr, ifp->ifidx, cmd, data,
-                                              len);
+               err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, data, len);
        else
-               err = brcmf_proto_cdc_query_dcmd(drvr, ifp->ifidx, cmd, data,
-                                                len);
+               err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len);
 
        if (err >= 0)
                err = 0;
index 16eb8202fb1e4678be1c5b180e2ba964ac43e6f5..77eae86e55c23318e439fa23118f3d10e4b33788 100644 (file)
 #ifndef _fwil_h_
 #define _fwil_h_
 
+/*******************************************************************************
+ * Dongle command codes that are interpreted by firmware
+ ******************************************************************************/
+#define BRCMF_C_GET_VERSION                    1
+#define BRCMF_C_UP                             2
+#define BRCMF_C_DOWN                           3
+#define BRCMF_C_SET_PROMISC                    10
+#define BRCMF_C_GET_RATE                       12
+#define BRCMF_C_GET_INFRA                      19
+#define BRCMF_C_SET_INFRA                      20
+#define BRCMF_C_GET_AUTH                       21
+#define BRCMF_C_SET_AUTH                       22
+#define BRCMF_C_GET_BSSID                      23
+#define BRCMF_C_GET_SSID                       25
+#define BRCMF_C_SET_SSID                       26
+#define BRCMF_C_TERMINATED                     28
+#define BRCMF_C_GET_CHANNEL                    29
+#define BRCMF_C_SET_CHANNEL                    30
+#define BRCMF_C_GET_SRL                                31
+#define BRCMF_C_SET_SRL                                32
+#define BRCMF_C_GET_LRL                                33
+#define BRCMF_C_SET_LRL                                34
+#define BRCMF_C_GET_RADIO                      37
+#define BRCMF_C_SET_RADIO                      38
+#define BRCMF_C_GET_PHYTYPE                    39
+#define BRCMF_C_SET_KEY                                45
+#define BRCMF_C_SET_PASSIVE_SCAN               49
+#define BRCMF_C_SCAN                           50
+#define BRCMF_C_SCAN_RESULTS                   51
+#define BRCMF_C_DISASSOC                       52
+#define BRCMF_C_REASSOC                                53
+#define BRCMF_C_SET_ROAM_TRIGGER               55
+#define BRCMF_C_SET_ROAM_DELTA                 57
+#define BRCMF_C_GET_BCNPRD                     75
+#define BRCMF_C_SET_BCNPRD                     76
+#define BRCMF_C_GET_DTIMPRD                    77
+#define BRCMF_C_SET_DTIMPRD                    78
+#define BRCMF_C_SET_COUNTRY                    84
+#define BRCMF_C_GET_PM                         85
+#define BRCMF_C_SET_PM                         86
+#define BRCMF_C_GET_CURR_RATESET               114
+#define BRCMF_C_GET_AP                         117
+#define BRCMF_C_SET_AP                         118
+#define BRCMF_C_GET_RSSI                       127
+#define BRCMF_C_GET_WSEC                       133
+#define BRCMF_C_SET_WSEC                       134
+#define BRCMF_C_GET_PHY_NOISE                  135
+#define BRCMF_C_GET_BSS_INFO                   136
+#define BRCMF_C_GET_BANDLIST                   140
+#define BRCMF_C_SET_SCB_TIMEOUT                        158
+#define BRCMF_C_GET_PHYLIST                    180
+#define BRCMF_C_SET_SCAN_CHANNEL_TIME          185
+#define BRCMF_C_SET_SCAN_UNASSOC_TIME          187
+#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON  201
+#define BRCMF_C_GET_VALID_CHANNELS             217
+#define BRCMF_C_GET_KEY_PRIMARY                        235
+#define BRCMF_C_SET_KEY_PRIMARY                        236
+#define BRCMF_C_SET_SCAN_PASSIVE_TIME          258
+#define BRCMF_C_GET_VAR                                262
+#define BRCMF_C_SET_VAR                                263
+
 s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
 s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
 s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data);
index ecabb04f33c3059c603513511cfd2679d23d6bb0..af17a5bc8b83bdab2ee9d5a5ff2ec17490cb7603 100644 (file)
 #define BRCMF_ARP_OL_HOST_AUTO_REPLY   0x00000004
 #define BRCMF_ARP_OL_PEER_AUTO_REPLY   0x00000008
 
+#define        BRCMF_BSS_INFO_VERSION  109 /* curr ver of brcmf_bss_info_le struct */
+#define BRCMF_BSS_RSSI_ON_CHANNEL      0x0002
+
+#define BRCMF_STA_ASSOC                        0x10            /* Associated */
+
+/* size of brcmf_scan_params not including variable length array */
+#define BRCMF_SCAN_PARAMS_FIXED_SIZE   64
+
+/* masks for channel and ssid count */
+#define BRCMF_SCAN_PARAMS_COUNT_MASK   0x0000ffff
+#define BRCMF_SCAN_PARAMS_NSSID_SHIFT  16
+
+/* primary (ie tx) key */
+#define BRCMF_PRIMARY_KEY              (1 << 1)
+#define DOT11_BSSTYPE_ANY              2
+#define BRCMF_ESCAN_REQ_VERSION                1
+
+#define BRCMF_MAXRATES_IN_SET          16      /* max # of rates in rateset */
 
 enum brcmf_fil_p2p_if_types {
        BRCMF_FIL_P2P_IF_CLIENT,
@@ -90,4 +108,290 @@ enum brcmf_tdls_manual_ep_ops {
        BRCMF_TDLS_MANUAL_EP_DISCOVERY = 6
 };
 
+/* Pattern matching filter. Specifies an offset within received packets to
+ * start matching, the pattern to match, the size of the pattern, and a bitmask
+ * that indicates which bits within the pattern should be matched.
+ */
+struct brcmf_pkt_filter_pattern_le {
+       /*
+        * Offset within received packet to start pattern matching.
+        * Offset '0' is the first byte of the ethernet header.
+        */
+       __le32 offset;
+       /* Size of the pattern.  Bitmask must be the same size.*/
+       __le32 size_bytes;
+       /*
+        * Variable length mask and pattern data. mask starts at offset 0.
+        * Pattern immediately follows mask.
+        */
+       u8 mask_and_pattern[1];
+};
+
+/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
+struct brcmf_pkt_filter_le {
+       __le32 id;              /* Unique filter id, specified by app. */
+       __le32 type;            /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
+       __le32 negate_match;    /* Negate the result of filter matches */
+       union {                 /* Filter definitions */
+               struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
+       } u;
+};
+
+/* IOVAR "pkt_filter_enable" parameter. */
+struct brcmf_pkt_filter_enable_le {
+       __le32 id;              /* Unique filter id */
+       __le32 enable;          /* Enable/disable bool */
+};
+
+/* BSS info structure
+ * Applications MUST CHECK ie_offset field and length field to access IEs and
+ * next bss_info structure in a vector (in struct brcmf_scan_results)
+ */
+struct brcmf_bss_info_le {
+       __le32 version;         /* version field */
+       __le32 length;          /* byte length of data in this record,
+                                * starting at version and including IEs
+                                */
+       u8 BSSID[ETH_ALEN];
+       __le16 beacon_period;   /* units are Kusec */
+       __le16 capability;      /* Capability information */
+       u8 SSID_len;
+       u8 SSID[32];
+       struct {
+               __le32 count;   /* # rates in this set */
+               u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
+       } rateset;              /* supported rates */
+       __le16 chanspec;        /* chanspec for bss */
+       __le16 atim_window;     /* units are Kusec */
+       u8 dtim_period; /* DTIM period */
+       __le16 RSSI;            /* receive signal strength (in dBm) */
+       s8 phy_noise;           /* noise (in dBm) */
+
+       u8 n_cap;               /* BSS is 802.11N Capable */
+       /* 802.11N BSS Capabilities (based on HT_CAP_*): */
+       __le32 nbss_cap;
+       u8 ctl_ch;              /* 802.11N BSS control channel number */
+       __le32 reserved32[1];   /* Reserved for expansion of BSS properties */
+       u8 flags;               /* flags */
+       u8 reserved[3]; /* Reserved for expansion of BSS properties */
+       u8 basic_mcs[MCSSET_LEN];       /* 802.11N BSS required MCS set */
+
+       __le16 ie_offset;       /* offset at which IEs start, from beginning */
+       __le32 ie_length;       /* byte length of Information Elements */
+       __le16 SNR;             /* average SNR of during frame reception */
+       /* Add new fields here */
+       /* variable length Information Elements */
+};
+
+struct brcm_rateset_le {
+       /* # rates in this set */
+       __le32 count;
+       /* rates in 500kbps units w/hi bit set if basic */
+       u8 rates[BRCMF_MAXRATES_IN_SET];
+};
+
+struct brcmf_ssid {
+       u32 SSID_len;
+       unsigned char SSID[32];
+};
+
+struct brcmf_ssid_le {
+       __le32 SSID_len;
+       unsigned char SSID[32];
+};
+
+struct brcmf_scan_params_le {
+       struct brcmf_ssid_le ssid_le;   /* default: {0, ""} */
+       u8 bssid[ETH_ALEN];     /* default: bcast */
+       s8 bss_type;            /* default: any,
+                                * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
+                                */
+       u8 scan_type;   /* flags, 0 use default */
+       __le32 nprobes;   /* -1 use default, number of probes per channel */
+       __le32 active_time;     /* -1 use default, dwell time per channel for
+                                * active scanning
+                                */
+       __le32 passive_time;    /* -1 use default, dwell time per channel
+                                * for passive scanning
+                                */
+       __le32 home_time;       /* -1 use default, dwell time for the
+                                * home channel between channel scans
+                                */
+       __le32 channel_num;     /* count of channels and ssids that follow
+                                *
+                                * low half is count of channels in
+                                * channel_list, 0 means default (use all
+                                * available channels)
+                                *
+                                * high half is entries in struct brcmf_ssid
+                                * array that follows channel_list, aligned for
+                                * s32 (4 bytes) meaning an odd channel count
+                                * implies a 2-byte pad between end of
+                                * channel_list and first ssid
+                                *
+                                * if ssid count is zero, single ssid in the
+                                * fixed parameter portion is assumed, otherwise
+                                * ssid in the fixed portion is ignored
+                                */
+       __le16 channel_list[1]; /* list of chanspecs */
+};
+
+struct brcmf_scan_results {
+       u32 buflen;
+       u32 version;
+       u32 count;
+       struct brcmf_bss_info_le bss_info_le[];
+};
+
+struct brcmf_escan_params_le {
+       __le32 version;
+       __le16 action;
+       __le16 sync_id;
+       struct brcmf_scan_params_le params_le;
+};
+
+struct brcmf_escan_result_le {
+       __le32 buflen;
+       __le32 version;
+       __le16 sync_id;
+       __le16 bss_count;
+       struct brcmf_bss_info_le bss_info_le;
+};
+
+#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \
+       sizeof(struct brcmf_bss_info_le))
+
+/* used for association with a specific BSSID and chanspec list */
+struct brcmf_assoc_params_le {
+       /* 00:00:00:00:00:00: broadcast scan */
+       u8 bssid[ETH_ALEN];
+       /* 0: all available channels, otherwise count of chanspecs in
+        * chanspec_list */
+       __le32 chanspec_num;
+       /* list of chanspecs */
+       __le16 chanspec_list[1];
+};
+
+/* used for join with or without a specific bssid and channel list */
+struct brcmf_join_params {
+       struct brcmf_ssid_le ssid_le;
+       struct brcmf_assoc_params_le params_le;
+};
+
+/* scan params for extended join */
+struct brcmf_join_scan_params_le {
+       u8 scan_type;           /* 0 use default, active or passive scan */
+       __le32 nprobes;         /* -1 use default, nr of probes per channel */
+       __le32 active_time;     /* -1 use default, dwell time per channel for
+                                * active scanning
+                                */
+       __le32 passive_time;    /* -1 use default, dwell time per channel
+                                * for passive scanning
+                                */
+       __le32 home_time;       /* -1 use default, dwell time for the home
+                                * channel between channel scans
+                                */
+};
+
+/* extended join params */
+struct brcmf_ext_join_params_le {
+       struct brcmf_ssid_le ssid_le;   /* {0, ""}: wildcard scan */
+       struct brcmf_join_scan_params_le scan_le;
+       struct brcmf_assoc_params_le assoc_le;
+};
+
+struct brcmf_wsec_key {
+       u32 index;              /* key index */
+       u32 len;                /* key length */
+       u8 data[WLAN_MAX_KEY_LEN];      /* key data */
+       u32 pad_1[18];
+       u32 algo;       /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
+       u32 flags;      /* misc flags */
+       u32 pad_2[3];
+       u32 iv_initialized;     /* has IV been initialized already? */
+       u32 pad_3;
+       /* Rx IV */
+       struct {
+               u32 hi; /* upper 32 bits of IV */
+               u16 lo; /* lower 16 bits of IV */
+       } rxiv;
+       u32 pad_4[2];
+       u8 ea[ETH_ALEN];        /* per station */
+};
+
+/*
+ * dongle requires same struct as above but with fields in little endian order
+ */
+struct brcmf_wsec_key_le {
+       __le32 index;           /* key index */
+       __le32 len;             /* key length */
+       u8 data[WLAN_MAX_KEY_LEN];      /* key data */
+       __le32 pad_1[18];
+       __le32 algo;    /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
+       __le32 flags;   /* misc flags */
+       __le32 pad_2[3];
+       __le32 iv_initialized;  /* has IV been initialized already? */
+       __le32 pad_3;
+       /* Rx IV */
+       struct {
+               __le32 hi;      /* upper 32 bits of IV */
+               __le16 lo;      /* lower 16 bits of IV */
+       } rxiv;
+       __le32 pad_4[2];
+       u8 ea[ETH_ALEN];        /* per station */
+};
+
+/* Used to get specific STA parameters */
+struct brcmf_scb_val_le {
+       __le32 val;
+       u8 ea[ETH_ALEN];
+};
+
+/* channel encoding */
+struct brcmf_channel_info_le {
+       __le32 hw_channel;
+       __le32 target_channel;
+       __le32 scan_channel;
+};
+
+struct brcmf_sta_info_le {
+       __le16  ver;            /* version of this struct */
+       __le16  len;            /* length in bytes of this structure */
+       __le16  cap;            /* sta's advertised capabilities */
+       __le32  flags;          /* flags defined below */
+       __le32  idle;           /* time since data pkt rx'd from sta */
+       u8      ea[ETH_ALEN];           /* Station address */
+       __le32  count;                  /* # rates in this set */
+       u8      rates[BRCMF_MAXRATES_IN_SET];   /* rates in 500kbps units */
+                                               /* w/hi bit set if basic */
+       __le32  in;             /* seconds elapsed since associated */
+       __le32  listen_interval_inms; /* Min Listen interval in ms for STA */
+       __le32  tx_pkts;        /* # of packets transmitted */
+       __le32  tx_failures;    /* # of packets failed */
+       __le32  rx_ucast_pkts;  /* # of unicast packets received */
+       __le32  rx_mcast_pkts;  /* # of multicast packets received */
+       __le32  tx_rate;        /* Rate of last successful tx frame */
+       __le32  rx_rate;        /* Rate of last successful rx frame */
+       __le32  rx_decrypt_succeeds;    /* # of packet decrypted successfully */
+       __le32  rx_decrypt_failures;    /* # of packet decrypted failed */
+};
+
+struct brcmf_chanspec_list {
+       __le32  count;          /* # of entries */
+       __le32  element[1];     /* variable length uint32 list */
+};
+
+/*
+ * WLC_E_PROBRESP_MSG
+ * WLC_E_P2P_PROBREQ_MSG
+ * WLC_E_ACTION_FRAME_RX
+ */
+struct brcmf_rx_mgmt_data {
+       __be16  version;
+       __be16  chanspec;
+       __be32  rssi;
+       __be32  mactime;
+       __be32  rate;
+};
+
 #endif /* FWIL_TYPES_H_ */
index d0cd0bf95c5af4393719a981d008049cde67756d..e9bdfdb95d8f06915fc734dd27053a3e092c046e 100644 (file)
@@ -27,7 +27,6 @@
 #include <brcmu_utils.h>
 #include <brcmu_wifi.h>
 #include "dhd.h"
-#include "dhd_proto.h"
 #include "dhd_dbg.h"
 #include "dhd_bus.h"
 #include "fwil.h"
@@ -36,6 +35,7 @@
 #include "fwsignal.h"
 #include "p2p.h"
 #include "wl_cfg80211.h"
+#include "proto.h"
 
 /**
  * DOC: Firmware Signalling
@@ -105,6 +105,7 @@ static struct {
 };
 #undef BRCMF_FWS_TLV_DEF
 
+
 static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
 {
        int i;
@@ -122,6 +123,12 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
 }
 #endif /* DEBUG */
 
+/*
+ * The PKTTAG tlv has additional bytes when firmware-signalling
+ * mode has REUSESEQ flag set.
+ */
+#define BRCMF_FWS_TYPE_SEQ_LEN                         2
+
 /*
  * flags used to enable tlv signalling from firmware.
  */
@@ -147,8 +154,15 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
 #define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST                        0x01
 #define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED              0x02
 
-#define BRCMF_FWS_RET_OK_NOSCHEDULE    0
-#define BRCMF_FWS_RET_OK_SCHEDULE      1
+#define BRCMF_FWS_RET_OK_NOSCHEDULE                    0
+#define BRCMF_FWS_RET_OK_SCHEDULE                      1
+
+#define BRCMF_FWS_MODE_REUSESEQ_SHIFT                  3       /* seq reuse */
+#define BRCMF_FWS_MODE_SET_REUSESEQ(x, val)    ((x) = \
+               ((x) & ~(1 << BRCMF_FWS_MODE_REUSESEQ_SHIFT)) | \
+               (((val) & 1) << BRCMF_FWS_MODE_REUSESEQ_SHIFT))
+#define BRCMF_FWS_MODE_GET_REUSESEQ(x) \
+               (((x) >> BRCMF_FWS_MODE_REUSESEQ_SHIFT) & 1)
 
 /**
  * enum brcmf_fws_skb_state - indicates processing state of skb.
@@ -171,6 +185,7 @@ enum brcmf_fws_skb_state {
  * @bus_flags: 2 bytes reserved for bus specific parameters
  * @if_flags: holds interface index and packet related flags.
  * @htod: host to device packet identifier (used in PKTTAG tlv).
+ * @htod_seq: this 16-bit is original seq number for every suppress packet.
  * @state: transmit state of the packet.
  * @mac: descriptor related to destination for this packet.
  *
@@ -181,6 +196,7 @@ struct brcmf_skbuff_cb {
        u16 bus_flags;
        u16 if_flags;
        u32 htod;
+       u16 htod_seq;
        enum brcmf_fws_skb_state state;
        struct brcmf_fws_mac_descriptor *mac;
 };
@@ -257,6 +273,22 @@ struct brcmf_skbuff_cb {
                        BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \
                        BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT)
 
+#define BRCMF_SKB_HTOD_SEQ_FROMFW_MASK                 0x2000
+#define BRCMF_SKB_HTOD_SEQ_FROMFW_SHIFT                        13
+#define BRCMF_SKB_HTOD_SEQ_FROMDRV_MASK                        0x1000
+#define BRCMF_SKB_HTOD_SEQ_FROMDRV_SHIFT               12
+#define BRCMF_SKB_HTOD_SEQ_NR_MASK                     0x0fff
+#define BRCMF_SKB_HTOD_SEQ_NR_SHIFT                    0
+
+#define brcmf_skb_htod_seq_set_field(skb, field, value) \
+       brcmu_maskset16(&(brcmf_skbcb(skb)->htod_seq), \
+                       BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \
+                       BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT, (value))
+#define brcmf_skb_htod_seq_get_field(skb, field) \
+       brcmu_maskget16(brcmf_skbcb(skb)->htod_seq, \
+                       BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \
+                       BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT)
+
 #define BRCMF_FWS_TXSTAT_GENERATION_MASK       0x80000000
 #define BRCMF_FWS_TXSTAT_GENERATION_SHIFT      31
 #define BRCMF_FWS_TXSTAT_FLAGS_MASK            0x78000000
@@ -265,8 +297,8 @@ struct brcmf_skbuff_cb {
 #define BRCMF_FWS_TXSTAT_FIFO_SHIFT            24
 #define BRCMF_FWS_TXSTAT_HSLOT_MASK            0x00FFFF00
 #define BRCMF_FWS_TXSTAT_HSLOT_SHIFT           8
-#define BRCMF_FWS_TXSTAT_PKTID_MASK            0x00FFFFFF
-#define BRCMF_FWS_TXSTAT_PKTID_SHIFT           0
+#define BRCMF_FWS_TXSTAT_FREERUN_MASK          0x000000FF
+#define BRCMF_FWS_TXSTAT_FREERUN_SHIFT         0
 
 #define brcmf_txstatus_get_field(txs, field) \
        brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \
@@ -443,6 +475,7 @@ struct brcmf_fws_info {
        unsigned long borrow_defer_timestamp;
        bool bus_flow_blocked;
        bool creditmap_received;
+       u8 mode;
 };
 
 /*
@@ -812,13 +845,16 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
        u16 data_offset = 0;
        u8 fillers;
        __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
+       __le16 pktseq = cpu_to_le16(brcmf_skbcb(skb)->htod_seq);
 
-       brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n",
+       brcmf_dbg(TRACE, "enter: %s, idx=%d hslot=%d htod %X seq %X\n",
                  entry->name, brcmf_skb_if_flags_get_field(skb, INDEX),
-                 le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff);
+                 (le32_to_cpu(pkttag) >> 8) & 0xffff,
+                 brcmf_skbcb(skb)->htod, brcmf_skbcb(skb)->htod_seq);
        if (entry->send_tim_signal)
                data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
-
+       if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode))
+               data_offset += BRCMF_FWS_TYPE_SEQ_LEN;
        /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
        data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN;
        fillers = round_up(data_offset, 4) - data_offset;
@@ -830,7 +866,12 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
        wlh[0] = BRCMF_FWS_TYPE_PKTTAG;
        wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN;
        memcpy(&wlh[2], &pkttag, sizeof(pkttag));
-       wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2;
+       if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
+               wlh[1] += BRCMF_FWS_TYPE_SEQ_LEN;
+               memcpy(&wlh[2 + BRCMF_FWS_TYPE_PKTTAG_LEN], &pktseq,
+                      sizeof(pktseq));
+       }
+       wlh += wlh[1] + 2;
 
        if (entry->send_tim_signal) {
                entry->send_tim_signal = 0;
@@ -875,6 +916,7 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
                /* create a dummy packet and sent that. The traffic          */
                /* bitmap info will automatically be attached to that packet */
                len = BRCMF_FWS_TYPE_PKTTAG_LEN + 2 +
+                     BRCMF_FWS_TYPE_SEQ_LEN +
                      BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 +
                      4 + fws->drvr->hdrlen;
                skb = brcmu_pkt_buf_get_skb(len);
@@ -884,6 +926,8 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
                skcb = brcmf_skbcb(skb);
                skcb->mac = entry;
                skcb->state = BRCMF_FWS_SKBSTATE_TIM;
+               skcb->htod = 0;
+               skcb->htod_seq = 0;
                bus = fws->drvr->bus_if;
                err = brcmf_fws_hdrpush(fws, skb);
                if (err == 0) {
@@ -1172,8 +1216,13 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
 {
        int prec = 2 * fifo;
        u32 *qfull_stat = &fws->stats.delayq_full_error;
-
        struct brcmf_fws_mac_descriptor *entry;
+       struct pktq *pq;
+       struct sk_buff_head *queue;
+       struct sk_buff *p_head;
+       struct sk_buff *p_tail;
+       u32 fr_new;
+       u32 fr_compare;
 
        entry = brcmf_skbcb(p)->mac;
        if (entry == NULL) {
@@ -1185,9 +1234,55 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
        if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) {
                prec += 1;
                qfull_stat = &fws->stats.supprq_full_error;
-       }
 
-       if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) {
+               /* Fix out of order delivery of frames. Dont assume frame    */
+               /* can be inserted at the end, but look for correct position */
+               pq = &entry->psq;
+               if (pktq_full(pq) || pktq_pfull(pq, prec)) {
+                       *qfull_stat += 1;
+                       return -ENFILE;
+               }
+               queue = &pq->q[prec].skblist;
+
+               p_head = skb_peek(queue);
+               p_tail = skb_peek_tail(queue);
+               fr_new = brcmf_skb_htod_tag_get_field(p, FREERUN);
+
+               while (p_head != p_tail) {
+                       fr_compare = brcmf_skb_htod_tag_get_field(p_tail,
+                                                                 FREERUN);
+                       /* be sure to handle wrap of 256 */
+                       if (((fr_new > fr_compare) &&
+                            ((fr_new - fr_compare) < 128)) ||
+                           ((fr_new < fr_compare) &&
+                            ((fr_compare - fr_new) > 128)))
+                               break;
+                       p_tail = skb_queue_prev(queue, p_tail);
+               }
+               /* Position found. Determine what to do */
+               if (p_tail == NULL) {
+                       /* empty list */
+                       __skb_queue_tail(queue, p);
+               } else {
+                       fr_compare = brcmf_skb_htod_tag_get_field(p_tail,
+                                                                 FREERUN);
+                       if (((fr_new > fr_compare) &&
+                            ((fr_new - fr_compare) < 128)) ||
+                           ((fr_new < fr_compare) &&
+                            ((fr_compare - fr_new) > 128))) {
+                               /* After tail */
+                               __skb_queue_after(queue, p_tail, p);
+                       } else {
+                               /* Before tail */
+                               __skb_insert(p, p_tail->prev, p_tail, queue);
+                       }
+               }
+
+               /* Complete the counters and statistics */
+               pq->len++;
+               if (pq->hi_prec < prec)
+                       pq->hi_prec = (u8) prec;
+       } else if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) {
                *qfull_stat += 1;
                return -ENFILE;
        }
@@ -1277,7 +1372,8 @@ done:
 }
 
 static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
-                                        struct sk_buff *skb, u32 genbit)
+                                        struct sk_buff *skb, u32 genbit,
+                                        u16 seq)
 {
        struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
        u32 hslot;
@@ -1298,6 +1394,14 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
 
        ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
        if (ret == 0)
+               brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
+               brcmf_skbcb(skb)->htod_seq = seq;
+               if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
+                       brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
+                       brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
+               } else {
+                       brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
+               }
                ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
                                    skb);
        if (ret != 0) {
@@ -1317,7 +1421,7 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
 
 static int
 brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
-                          u32 genbit)
+                     u32 genbit, u16 seq)
 {
        u32 fifo;
        int ret;
@@ -1360,8 +1464,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
        if (entry->suppressed && entry->suppr_transit_count)
                entry->suppr_transit_count--;
 
-       brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags,
-                 skcb->htod);
+       brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags,
+                 skcb->htod, seq);
 
        /* pick up the implicit credit from this packet */
        fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
@@ -1374,7 +1478,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
        brcmf_fws_macdesc_return_req_credit(skb);
 
        if (!remove_from_hanger)
-               ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit);
+               ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit,
+                                                   seq);
 
        if (remove_from_hanger || ret)
                brcmf_txfinalize(fws->drvr, skb, true);
@@ -1406,10 +1511,12 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
 static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
 {
        __le32 status_le;
+       __le16 seq_le;
        u32 status;
        u32 hslot;
        u32 genbit;
        u8 flags;
+       u16 seq;
 
        fws->stats.txs_indicate++;
        memcpy(&status_le, data, sizeof(status_le));
@@ -1417,9 +1524,16 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
        flags = brcmf_txstatus_get_field(status, FLAGS);
        hslot = brcmf_txstatus_get_field(status, HSLOT);
        genbit = brcmf_txstatus_get_field(status, GENERATION);
+       if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
+               memcpy(&seq_le, &data[BRCMF_FWS_TYPE_PKTTAG_LEN],
+                      sizeof(seq_le));
+               seq = le16_to_cpu(seq_le);
+       } else {
+               seq = 0;
+       }
 
        brcmf_fws_lock(fws);
-       brcmf_fws_txs_process(fws, flags, hslot, genbit);
+       brcmf_fws_txs_process(fws, flags, hslot, genbit, seq);
        brcmf_fws_unlock(fws);
        return BRCMF_FWS_RET_OK_NOSCHEDULE;
 }
@@ -1610,8 +1724,8 @@ static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
        struct brcmf_fws_mac_descriptor *entry = skcb->mac;
        u8 flags;
 
-       brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
-       brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
+       if (skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED)
+               brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
        flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST;
        if (brcmf_skb_if_flags_get_field(p, REQUESTED)) {
                /*
@@ -1652,7 +1766,7 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
                fws->stats.rollback_failed++;
                hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
                brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
-                                     hslot, 0);
+                                     hslot, 0, 0);
        } else {
                fws->stats.rollback_success++;
                brcmf_fws_return_credits(fws, fifo, 1);
@@ -1732,6 +1846,8 @@ static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p,
        struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
        int rc, hslot;
 
+       skcb->htod = 0;
+       skcb->htod_seq = 0;
        hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
        brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
        brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]);
@@ -1908,6 +2024,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
        struct brcmf_fws_info *fws;
        u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS;
        int rc;
+       u32 mode;
 
        drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL);
        if (!drvr->fws) {
@@ -1966,6 +2083,18 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
        if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1))
                brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n");
 
+       /* Enable seq number reuse, if supported */
+       if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) {
+               if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) {
+                       mode = 0;
+                       BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1);
+                       if (brcmf_fil_iovar_int_set(drvr->iflist[0],
+                                                   "wlfc_mode", mode) == 0) {
+                               BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1);
+                       }
+               }
+       }
+
        brcmf_fws_hanger_init(&fws->hanger);
        brcmf_fws_macdesc_init(&fws->desc.other, NULL, 0);
        brcmf_fws_macdesc_set_name(fws, &fws->desc.other);
@@ -2022,7 +2151,7 @@ void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
        }
        brcmf_fws_lock(fws);
        hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
-       brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0);
+       brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0);
        brcmf_fws_unlock(fws);
 }
 
index 4a2293041821ff708c6cefef86ed21406f18266c..d3180360725925c40f6e59bf09bdfb28e18a4300 100644 (file)
@@ -812,7 +812,7 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
                        struct ieee80211_channel *chan = request->channels[i];
 
                        if (chan->flags & (IEEE80211_CHAN_RADAR |
-                                          IEEE80211_CHAN_PASSIVE_SCAN))
+                                          IEEE80211_CHAN_NO_IR))
                                continue;
 
                        chanspecs[i] = channel_to_chanspec(&p2p->cfg->d11inf,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
new file mode 100644 (file)
index 0000000..87eb2bd
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013 Broadcom Corporation
+ *
+ * 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 <linux/types.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+
+#include <brcmu_wifi.h>
+#include "dhd.h"
+#include "dhd_dbg.h"
+#include "proto.h"
+#include "bcdc.h"
+
+
+int brcmf_proto_attach(struct brcmf_pub *drvr)
+{
+       struct brcmf_proto *proto;
+
+       proto = kzalloc(sizeof(*proto), GFP_ATOMIC);
+       if (!proto)
+               goto fail;
+
+       drvr->proto = proto;
+       /* BCDC protocol is only protocol supported for the moment */
+       if (brcmf_proto_bcdc_attach(drvr))
+               goto fail;
+
+       if ((proto->hdrpush == NULL) || (proto->hdrpull == NULL) ||
+           (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL)) {
+               brcmf_err("Not all proto handlers have been installed\n");
+               goto fail;
+       }
+       return 0;
+
+fail:
+       kfree(proto);
+       drvr->proto = NULL;
+       return -ENOMEM;
+}
+
+void brcmf_proto_detach(struct brcmf_pub *drvr)
+{
+       if (drvr->proto) {
+               brcmf_proto_bcdc_detach(drvr);
+               kfree(drvr->proto);
+               drvr->proto = NULL;
+       }
+}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.h b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
new file mode 100644 (file)
index 0000000..8de1b3b
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013 Broadcom Corporation
+ *
+ * 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.
+ */
+#ifndef BRCMFMAC_PROTO_H
+#define BRCMFMAC_PROTO_H
+
+struct brcmf_proto {
+       void (*hdrpush)(struct brcmf_pub *drvr, int ifidx, u8 offset,
+                       struct sk_buff *skb);
+       int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
+                      struct sk_buff *skb);
+       int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
+                         void *buf, uint len);
+       int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
+                       uint len);
+       void *pd;
+};
+
+
+int brcmf_proto_attach(struct brcmf_pub *drvr);
+void brcmf_proto_detach(struct brcmf_pub *drvr);
+
+static inline void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
+                                      u8 offset, struct sk_buff *skb)
+{
+       drvr->proto->hdrpush(drvr, ifidx, offset, skb);
+}
+static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws,
+                                     u8 *ifidx, struct sk_buff *skb)
+{
+       return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb);
+}
+static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
+                                        uint cmd, void *buf, uint len)
+{
+       return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len);
+}
+static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx,
+                                      uint cmd, void *buf, uint len)
+{
+       return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len);
+}
+
+
+#endif /* BRCMFMAC_PROTO_H */
index 3c67529b90743123691d08aa7ed4d3fdb4a45c6d..4d7d51f9571637de5f9a0a7423f68336af6d2a41 100644 (file)
@@ -89,7 +89,7 @@ TRACE_EVENT(brcmf_hexdump,
        TP_printk("hexdump [addr=%lx, length=%lu]", __entry->addr, __entry->len)
 );
 
-TRACE_EVENT(brcmf_bdchdr,
+TRACE_EVENT(brcmf_bcdchdr,
        TP_PROTO(void *data),
        TP_ARGS(data),
        TP_STRUCT__entry(
@@ -107,24 +107,35 @@ TRACE_EVENT(brcmf_bdchdr,
                memcpy(__get_dynamic_array(signal),
                       (u8 *)data + 4, __entry->siglen);
        ),
-       TP_printk("bdc: prio=%d siglen=%d", __entry->prio, __entry->siglen)
+       TP_printk("bcdc: prio=%d siglen=%d", __entry->prio, __entry->siglen)
 );
 
+#ifndef SDPCM_RX
+#define SDPCM_RX       0
+#endif
+#ifndef SDPCM_TX
+#define SDPCM_TX       1
+#endif
+#ifndef SDPCM_GLOM
+#define SDPCM_GLOM     2
+#endif
+
 TRACE_EVENT(brcmf_sdpcm_hdr,
-       TP_PROTO(bool tx, void *data),
-       TP_ARGS(tx, data),
+       TP_PROTO(u8 dir, void *data),
+       TP_ARGS(dir, data),
        TP_STRUCT__entry(
-               __field(u8, tx)
+               __field(u8, dir)
                __field(u16, len)
-               __array(u8, hdr, 12)
+               __dynamic_array(u8, hdr, dir == SDPCM_GLOM ? 20 : 12)
        ),
        TP_fast_assign(
-               memcpy(__entry->hdr, data, 12);
-               __entry->len = __entry->hdr[0] | (__entry->hdr[1] << 8);
-               __entry->tx = tx ? 1 : 0;
+               memcpy(__get_dynamic_array(hdr), data, dir == SDPCM_GLOM ? 20 : 12);
+               __entry->len = *(u8 *)data | (*((u8 *)data + 1) << 8);
+               __entry->dir = dir;
        ),
-       TP_printk("sdpcm: %s len %u, seq %d", __entry->tx ? "TX" : "RX",
-                 __entry->len, __entry->hdr[4])
+       TP_printk("sdpcm: %s len %u, seq %d",
+                 __entry->dir == SDPCM_RX ? "RX" : "TX",
+                 __entry->len, ((u8 *)__get_dynamic_array(hdr))[4])
 );
 
 #ifdef CONFIG_BRCM_TRACING
index 422f44c631756b2332dc10d4c1fb24c8172343ff..51c4de054b15e9c89c154acb93e3fff79e0c4ffa 100644 (file)
@@ -1255,7 +1255,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
        bus->chiprev = bus_pub->chiprev;
 
        /* Attach to the common driver interface */
-       ret = brcmf_attach(0, dev);
+       ret = brcmf_attach(dev);
        if (ret) {
                brcmf_err("brcmf_attach failed\n");
                goto fail;
@@ -1454,7 +1454,7 @@ static int brcmf_usb_resume(struct usb_interface *intf)
        struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
 
        brcmf_dbg(USB, "Enter\n");
-       if (!brcmf_attach(0, devinfo->dev))
+       if (!brcmf_attach(devinfo->dev))
                return brcmf_bus_start(&usb->dev);
 
        return 0;
index 571f013cebbb0d0a80f32e2351975b659d7d53d1..3966fe0fcfd971418fb3ca22bfc9fcaddf7afaf7 100644 (file)
@@ -202,9 +202,9 @@ static struct ieee80211_supported_band __wl_band_5ghz_a = {
 
 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
  * By default world regulatory domain defined in reg.c puts the flags
- * NL80211_RRF_PASSIVE_SCAN and NL80211_RRF_NO_IBSS for 5GHz channels (for
- * 36..48 and 149..165). With respect to these flags, wpa_supplicant doesn't
- * start p2p operations on 5GHz channels. All the changes in world regulatory
+ * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
+ * With respect to these flags, wpa_supplicant doesn't * start p2p
+ * operations on 5GHz channels. All the changes in world regulatory
  * domain are to be done here.
  */
 static const struct ieee80211_regdomain brcmf_regdom = {
@@ -2556,8 +2556,8 @@ brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
                ch_bss.band == ch_bss_info_le.band &&
                bss_info_le->SSID_len == bss->SSID_len &&
                !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
-               if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
-                       (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
+               if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
+                       (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
                        s16 bss_rssi = le16_to_cpu(bss->RSSI);
                        s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
 
@@ -2566,13 +2566,13 @@ brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
                        */
                        if (bss_info_rssi > bss_rssi)
                                bss->RSSI = bss_info_le->RSSI;
-               } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
-                       (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
+               } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
+                       (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
                        /* preserve the on-channel rssi measurement
                        * if the new measurement is off channel
                        */
                        bss->RSSI = bss_info_le->RSSI;
-                       bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
+                       bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
                }
                return 1;
        }
@@ -3973,11 +3973,12 @@ brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
 
 static int
 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
-                      struct ieee80211_channel *chan, bool offchan,
-                      unsigned int wait, const u8 *buf, size_t len,
-                      bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+                      struct cfg80211_mgmt_tx_params *params, u64 *cookie)
 {
        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+       struct ieee80211_channel *chan = params->chan;
+       const u8 *buf = params->buf;
+       size_t len = params->len;
        const struct ieee80211_mgmt *mgmt;
        struct brcmf_cfg80211_vif *vif;
        s32 err = 0;
@@ -4341,7 +4342,7 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
        wiphy->max_remain_on_channel_duration = 5000;
        brcmf_wiphy_pno_params(wiphy);
        brcmf_dbg(INFO, "Registering custom regulatory\n");
-       wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+       wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
        wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
        err = wiphy_register(wiphy);
        if (err < 0) {
@@ -5197,10 +5198,10 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
                                        if (channel & WL_CHAN_RADAR)
                                                band_chan_arr[index].flags |=
                                                        (IEEE80211_CHAN_RADAR |
-                                                       IEEE80211_CHAN_NO_IBSS);
+                                                       IEEE80211_CHAN_NO_IR);
                                        if (channel & WL_CHAN_PASSIVE)
                                                band_chan_arr[index].flags |=
-                                                   IEEE80211_CHAN_PASSIVE_SCAN;
+                                                   IEEE80211_CHAN_NO_IR;
                                }
                        }
                        if (!update)
index cc87926f505562335a02c605541c739725cf1a03..635ae034c7e5d8d149cec933b55d7405678fa6ba 100644 (file)
 
 #define BRCM_2GHZ_2412_2462    REG_RULE(2412-10, 2462+10, 40, 0, 19, 0)
 #define BRCM_2GHZ_2467_2472    REG_RULE(2467-10, 2472+10, 20, 0, 19, \
-                                        NL80211_RRF_PASSIVE_SCAN | \
-                                        NL80211_RRF_NO_IBSS)
+                                        NL80211_RRF_NO_IR)
 
 #define BRCM_5GHZ_5180_5240    REG_RULE(5180-10, 5240+10, 40, 0, 21, \
-                                        NL80211_RRF_PASSIVE_SCAN | \
-                                        NL80211_RRF_NO_IBSS)
+                                        NL80211_RRF_NO_IR)
 #define BRCM_5GHZ_5260_5320    REG_RULE(5260-10, 5320+10, 40, 0, 21, \
-                                        NL80211_RRF_PASSIVE_SCAN | \
                                         NL80211_RRF_DFS | \
-                                        NL80211_RRF_NO_IBSS)
+                                        NL80211_RRF_NO_IR)
 #define BRCM_5GHZ_5500_5700    REG_RULE(5500-10, 5700+10, 40, 0, 21, \
-                                        NL80211_RRF_PASSIVE_SCAN | \
                                         NL80211_RRF_DFS | \
-                                        NL80211_RRF_NO_IBSS)
+                                        NL80211_RRF_NO_IR)
 #define BRCM_5GHZ_5745_5825    REG_RULE(5745-10, 5825+10, 40, 0, 21, \
-                                        NL80211_RRF_PASSIVE_SCAN | \
-                                        NL80211_RRF_NO_IBSS)
+                                        NL80211_RRF_NO_IR)
 
 static const struct ieee80211_regdomain brcms_regdom_x2 = {
        .n_reg_rules = 6,
@@ -395,7 +390,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
                brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
 
        brcms_b_set_chanspec(wlc->hw, chanspec,
-                             !!(ch->flags & IEEE80211_CHAN_PASSIVE_SCAN),
+                             !!(ch->flags & IEEE80211_CHAN_NO_IR),
                              &txpwr);
 }
 
@@ -657,8 +652,8 @@ static void brcms_reg_apply_radar_flags(struct wiphy *wiphy)
                 */
                if (!(ch->flags & IEEE80211_CHAN_DISABLED))
                        ch->flags |= IEEE80211_CHAN_RADAR |
-                                    IEEE80211_CHAN_NO_IBSS |
-                                    IEEE80211_CHAN_PASSIVE_SCAN;
+                                    IEEE80211_CHAN_NO_IR |
+                                    IEEE80211_CHAN_NO_IR;
        }
 }
 
@@ -684,18 +679,15 @@ brcms_reg_apply_beaconing_flags(struct wiphy *wiphy,
                                continue;
 
                        if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
-                               rule = freq_reg_info(wiphy, ch->center_freq);
+                               rule = freq_reg_info(wiphy,
+                                                    MHZ_TO_KHZ(ch->center_freq));
                                if (IS_ERR(rule))
                                        continue;
 
-                               if (!(rule->flags & NL80211_RRF_NO_IBSS))
-                                       ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
-                               if (!(rule->flags & NL80211_RRF_PASSIVE_SCAN))
-                                       ch->flags &=
-                                               ~IEEE80211_CHAN_PASSIVE_SCAN;
+                               if (!(rule->flags & NL80211_RRF_NO_IR))
+                                       ch->flags &= ~IEEE80211_CHAN_NO_IR;
                        } else if (ch->beacon_found) {
-                               ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
-                                              IEEE80211_CHAN_PASSIVE_SCAN);
+                               ch->flags &= ~IEEE80211_CHAN_NO_IR;
                        }
                }
        }
@@ -775,8 +767,8 @@ void brcms_c_regd_init(struct brcms_c_info *wlc)
        }
 
        wlc->wiphy->reg_notifier = brcms_reg_notifier;
-       wlc->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
-                            WIPHY_FLAG_STRICT_REGULATORY;
+       wlc->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
+                                       REGULATORY_STRICT_REG;
        wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain);
        brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER);
 }
index edc5d105ff980e40e1ad2221a4c7686f87b0cea1..e71ce8c842a22f3a337cf1bbf4a08dc0e3e52b70 100644 (file)
@@ -125,13 +125,13 @@ static struct ieee80211_channel brcms_2ghz_chantable[] = {
        CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
        CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
        CHAN2GHZ(12, 2467,
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+                IEEE80211_CHAN_NO_IR |
                 IEEE80211_CHAN_NO_HT40PLUS),
        CHAN2GHZ(13, 2472,
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+                IEEE80211_CHAN_NO_IR |
                 IEEE80211_CHAN_NO_HT40PLUS),
        CHAN2GHZ(14, 2484,
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+                IEEE80211_CHAN_NO_IR |
                 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS |
                 IEEE80211_CHAN_NO_OFDM)
 };
@@ -144,51 +144,51 @@ static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
        CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
        /* UNII-2 */
        CHAN5GHZ(52,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
        CHAN5GHZ(56,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
        CHAN5GHZ(60,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
        CHAN5GHZ(64,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
        /* MID */
        CHAN5GHZ(100,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
        CHAN5GHZ(104,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
        CHAN5GHZ(108,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
        CHAN5GHZ(112,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
        CHAN5GHZ(116,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
        CHAN5GHZ(120,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
        CHAN5GHZ(124,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
        CHAN5GHZ(128,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
        CHAN5GHZ(132,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
        CHAN5GHZ(136,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
        CHAN5GHZ(140,
-                IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
+                IEEE80211_CHAN_RADAR |
+                IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS |
                 IEEE80211_CHAN_NO_HT40MINUS),
        /* UNII-3 */
        CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
index ebdcdf44f1557de4230125be8862e6f333fccbc2..d3acc85932a569024a51d4b9d68b6dbc79dcfec8 100644 (file)
@@ -108,9 +108,9 @@ static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
        struct hwbus_priv *self = dev_id;
 
        if (self->core) {
-               sdio_claim_host(self->func);
+               cw1200_sdio_lock(self);
                cw1200_irq_handler(self->core);
-               sdio_release_host(self->func);
+               cw1200_sdio_unlock(self);
                return IRQ_HANDLED;
        } else {
                return IRQ_NONE;
index ee3c19037aac5e039fe023a0fa3fa3b7d08f503d..9afcd4ce3368d37908a055df935f29cf4032f259 100644 (file)
@@ -173,8 +173,9 @@ void cw1200_scan_work(struct work_struct *work)
                        cw1200_set_pm(priv, &priv->powersave_mode);
 
                if (priv->scan.status < 0)
-                       wiphy_dbg(priv->hw->wiphy, "[SCAN] Scan failed (%d).\n",
-                                 priv->scan.status);
+                       wiphy_warn(priv->hw->wiphy,
+                                  "[SCAN] Scan failed (%d).\n",
+                                  priv->scan.status);
                else if (priv->scan.req)
                        wiphy_dbg(priv->hw->wiphy,
                                  "[SCAN] Scan completed.\n");
@@ -197,9 +198,9 @@ void cw1200_scan_work(struct work_struct *work)
                        if ((*it)->band != first->band)
                                break;
                        if (((*it)->flags ^ first->flags) &
-                                       IEEE80211_CHAN_PASSIVE_SCAN)
+                                       IEEE80211_CHAN_NO_IR)
                                break;
-                       if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
+                       if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
                            (*it)->max_power != first->max_power)
                                break;
                }
@@ -210,7 +211,7 @@ void cw1200_scan_work(struct work_struct *work)
                else
                        scan.max_tx_rate = WSM_TRANSMIT_RATE_1;
                scan.num_probes =
-                       (first->flags & IEEE80211_CHAN_PASSIVE_SCAN) ? 0 : 2;
+                       (first->flags & IEEE80211_CHAN_NO_IR) ? 0 : 2;
                scan.num_ssids = priv->scan.n_ssids;
                scan.ssids = &priv->scan.ssids[0];
                scan.num_channels = it - priv->scan.curr;
@@ -233,7 +234,7 @@ void cw1200_scan_work(struct work_struct *work)
                }
                for (i = 0; i < scan.num_channels; ++i) {
                        scan.ch[i].number = priv->scan.curr[i]->hw_value;
-                       if (priv->scan.curr[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
+                       if (priv->scan.curr[i]->flags & IEEE80211_CHAN_NO_IR) {
                                scan.ch[i].min_chan_time = 50;
                                scan.ch[i].max_chan_time = 100;
                        } else {
@@ -241,7 +242,7 @@ void cw1200_scan_work(struct work_struct *work)
                                scan.ch[i].max_chan_time = 25;
                        }
                }
-               if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
+               if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
                    priv->scan.output_power != first->max_power) {
                        priv->scan.output_power = first->max_power;
                        wsm_set_output_power(priv,
index f8ab193009cd9f3044a3d8846d4da4e7cbaec3e5..3aba49259ef1886d09157559977cb7f72ac1d944 100644 (file)
@@ -1930,10 +1930,10 @@ static int ipw2100_wdev_init(struct net_device *dev)
                        bg_band->channels[i].max_power = geo->bg[i].max_power;
                        if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
                                bg_band->channels[i].flags |=
-                                       IEEE80211_CHAN_PASSIVE_SCAN;
+                                       IEEE80211_CHAN_NO_IR;
                        if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
                                bg_band->channels[i].flags |=
-                                       IEEE80211_CHAN_NO_IBSS;
+                                       IEEE80211_CHAN_NO_IR;
                        if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
                                bg_band->channels[i].flags |=
                                        IEEE80211_CHAN_RADAR;
@@ -6362,7 +6362,6 @@ out:
                                   &ipw2100_attribute_group);
 
                free_libipw(dev, 0);
-               pci_set_drvdata(pci_dev, NULL);
        }
 
        pci_iounmap(pci_dev, ioaddr);
index 81903e33d5b1bd4779681da798dc0183c0638f48..9244b3661d343d8908bb72ec3a4516391d1d9900 100644 (file)
@@ -11472,10 +11472,10 @@ static int ipw_wdev_init(struct net_device *dev)
                        bg_band->channels[i].max_power = geo->bg[i].max_power;
                        if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
                                bg_band->channels[i].flags |=
-                                       IEEE80211_CHAN_PASSIVE_SCAN;
+                                       IEEE80211_CHAN_NO_IR;
                        if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
                                bg_band->channels[i].flags |=
-                                       IEEE80211_CHAN_NO_IBSS;
+                                       IEEE80211_CHAN_NO_IR;
                        if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
                                bg_band->channels[i].flags |=
                                        IEEE80211_CHAN_RADAR;
@@ -11511,10 +11511,10 @@ static int ipw_wdev_init(struct net_device *dev)
                        a_band->channels[i].max_power = geo->a[i].max_power;
                        if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
                                a_band->channels[i].flags |=
-                                       IEEE80211_CHAN_PASSIVE_SCAN;
+                                       IEEE80211_CHAN_NO_IR;
                        if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
                                a_band->channels[i].flags |=
-                                       IEEE80211_CHAN_NO_IBSS;
+                                       IEEE80211_CHAN_NO_IR;
                        if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
                                a_band->channels[i].flags |=
                                        IEEE80211_CHAN_RADAR;
index dea3b50d68b9c5bcfc1c95794262992bc59d917d..0487461ae4da22053607bb49178e296787e18dc3 100644 (file)
@@ -1595,7 +1595,7 @@ il3945_get_channels_for_scan(struct il_priv *il, enum ieee80211_band band,
                 *  and use long active_dwell time.
                 */
                if (!is_active || il_is_channel_passive(ch_info) ||
-                   (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
+                   (chan->flags & IEEE80211_CHAN_NO_IR)) {
                        scan_ch->type = 0;      /* passive */
                        if (IL_UCODE_API(il->ucode_ver) == 1)
                                scan_ch->active_dwell =
@@ -2396,8 +2396,7 @@ __il3945_up(struct il_priv *il)
                clear_bit(S_RFKILL, &il->status);
        else {
                set_bit(S_RFKILL, &il->status);
-               IL_WARN("Radio disabled by HW RF Kill switch\n");
-               return -ENODEV;
+               return -ERFKILL;
        }
 
        _il_wr(il, CSR_INT, 0xFFFFFFFF);
@@ -3575,9 +3574,9 @@ il3945_setup_mac(struct il_priv *il)
        hw->wiphy->interface_modes =
            BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
 
-       hw->wiphy->flags |=
-           WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS |
-           WIPHY_FLAG_IBSS_RSN;
+       hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+       hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
+                                      REGULATORY_DISABLE_BEACON_HINTS;
 
        hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
index 3982ab76f3755fdbda4f0cab89aa6cca537a8f43..43f488a8cda21790a646dcd4efa4ffd04d445c96 100644 (file)
@@ -805,7 +805,7 @@ il4965_get_channels_for_scan(struct il_priv *il, struct ieee80211_vif *vif,
                }
 
                if (!is_active || il_is_channel_passive(ch_info) ||
-                   (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
+                   (chan->flags & IEEE80211_CHAN_NO_IR))
                        scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
                else
                        scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
@@ -5778,9 +5778,9 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
        hw->wiphy->interface_modes =
            BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
 
-       hw->wiphy->flags |=
-           WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS |
-           WIPHY_FLAG_IBSS_RSN;
+       hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+       hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
+                                      REGULATORY_DISABLE_BEACON_HINTS;
 
        /*
         * For now, disable PS by default because it affects
index b03e22ef5462d929ea20ffad72a4a01ff067c4a4..a27b14cfeaec05753bb64fe8708ec7c25065995c 100644 (file)
@@ -3445,10 +3445,10 @@ il_init_geos(struct il_priv *il)
 
                if (il_is_channel_valid(ch)) {
                        if (!(ch->flags & EEPROM_CHANNEL_IBSS))
-                               geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
+                               geo_ch->flags |= IEEE80211_CHAN_NO_IR;
 
                        if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
-                               geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
+                               geo_ch->flags |= IEEE80211_CHAN_NO_IR;
 
                        if (ch->flags & EEPROM_CHANNEL_RADAR)
                                geo_ch->flags |= IEEE80211_CHAN_RADAR;
index eff26501d60a63407fba5b8cff66778d612df54e..3a487a3bb5de8fd62c896409df62562712e41239 100644 (file)
@@ -567,12 +567,12 @@ il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
                                      flags & IEEE80211_CHAN_RADAR ?
                                      " (IEEE 802.11h required)" : "",
                                      ((channels[i].
-                                       flags & IEEE80211_CHAN_NO_IBSS) ||
+                                       flags & IEEE80211_CHAN_NO_IR) ||
                                       (channels[i].
                                        flags & IEEE80211_CHAN_RADAR)) ? "" :
                                      ", IBSS",
                                      channels[i].
-                                     flags & IEEE80211_CHAN_PASSIVE_SCAN ?
+                                     flags & IEEE80211_CHAN_NO_IR ?
                                      "passive only" : "active/passive");
        }
        supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ);
@@ -594,12 +594,12 @@ il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
                                      flags & IEEE80211_CHAN_RADAR ?
                                      " (IEEE 802.11h required)" : "",
                                      ((channels[i].
-                                       flags & IEEE80211_CHAN_NO_IBSS) ||
+                                       flags & IEEE80211_CHAN_NO_IR) ||
                                       (channels[i].
                                        flags & IEEE80211_CHAN_RADAR)) ? "" :
                                      ", IBSS",
                                      channels[i].
-                                     flags & IEEE80211_CHAN_PASSIVE_SCAN ?
+                                     flags & IEEE80211_CHAN_NO_IR ?
                                      "passive only" : "active/passive");
        }
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
index d94f8ab15004cb93f2e757f92a91fd3e669759cb..f69301e505ee0e8968d5a9b90f9dcb3404c1f843 100644 (file)
@@ -352,12 +352,12 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
                                        channels[i].max_power,
                                        channels[i].flags & IEEE80211_CHAN_RADAR ?
                                        " (IEEE 802.11h required)" : "",
-                                       ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
+                                       ((channels[i].flags & IEEE80211_CHAN_NO_IR)
                                        || (channels[i].flags &
                                        IEEE80211_CHAN_RADAR)) ? "" :
                                        ", IBSS",
                                        channels[i].flags &
-                                       IEEE80211_CHAN_PASSIVE_SCAN ?
+                                       IEEE80211_CHAN_NO_IR ?
                                        "passive only" : "active/passive");
        }
        supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
@@ -375,12 +375,12 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
                                        channels[i].max_power,
                                        channels[i].flags & IEEE80211_CHAN_RADAR ?
                                        " (IEEE 802.11h required)" : "",
-                                       ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
+                                       ((channels[i].flags & IEEE80211_CHAN_NO_IR)
                                        || (channels[i].flags &
                                        IEEE80211_CHAN_RADAR)) ? "" :
                                        ", IBSS",
                                        channels[i].flags &
-                                       IEEE80211_CHAN_PASSIVE_SCAN ?
+                                       IEEE80211_CHAN_NO_IR ?
                                        "passive only" : "active/passive");
        }
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
index cae4d3182e334f9451e38d0afada8a8468785195..217f1ca321a0fecb7aaa876a5a22b5ec214b5818 100644 (file)
@@ -155,9 +155,9 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
                        ARRAY_SIZE(iwlagn_iface_combinations_dualmode);
        }
 
-       hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
-                           WIPHY_FLAG_DISABLE_BEACON_HINTS |
-                           WIPHY_FLAG_IBSS_RSN;
+       hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+       hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
+                                      REGULATORY_DISABLE_BEACON_HINTS;
 
 #ifdef CONFIG_PM_SLEEP
        if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
index 35e0ee8b4e5b64162ecdb2287ae53ab3acd5ee4b..928f8640a0a7965aebfb5c429265ac71a4970f88 100644 (file)
@@ -544,7 +544,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
                channel = chan->hw_value;
                scan_ch->channel = cpu_to_le16(channel);
 
-               if (!is_active || (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
+               if (!is_active || (chan->flags & IEEE80211_CHAN_NO_IR))
                        scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
                else
                        scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
index 4c887f3659089ea3451bc9cc4f2a8dc44c764601..f4a6d317a023aad241ac4f15351a1cc2deae7a2c 100644 (file)
@@ -614,10 +614,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
                        channel->flags = IEEE80211_CHAN_NO_HT40;
 
                        if (!(eeprom_ch->flags & EEPROM_CHANNEL_IBSS))
-                               channel->flags |= IEEE80211_CHAN_NO_IBSS;
+                               channel->flags |= IEEE80211_CHAN_NO_IR;
 
                        if (!(eeprom_ch->flags & EEPROM_CHANNEL_ACTIVE))
-                               channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
+                               channel->flags |= IEEE80211_CHAN_NO_IR;
 
                        if (eeprom_ch->flags & EEPROM_CHANNEL_RADAR)
                                channel->flags |= IEEE80211_CHAN_RADAR;
index b76a9a8fc0b3dbe831f74ce7d20a811e6cf17ada..2fab203d30275c658a5e4e6a8c296d9595a4ce73 100644 (file)
@@ -223,10 +223,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
                        channel->flags |= IEEE80211_CHAN_NO_160MHZ;
 
                if (!(ch_flags & NVM_CHANNEL_IBSS))
-                       channel->flags |= IEEE80211_CHAN_NO_IBSS;
+                       channel->flags |= IEEE80211_CHAN_NO_IR;
 
                if (!(ch_flags & NVM_CHANNEL_ACTIVE))
-                       channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
+                       channel->flags |= IEEE80211_CHAN_NO_IR;
 
                if (ch_flags & NVM_CHANNEL_RADAR)
                        channel->flags |= IEEE80211_CHAN_RADAR;
index 74bc2c8af06d62fb360de4357621dca50201a8c2..b56c989ad784d97b00e293209f02bc69d34f31c5 100644 (file)
@@ -199,9 +199,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
        if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8)
                hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
 
-       hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
-                           WIPHY_FLAG_DISABLE_BEACON_HINTS |
-                           WIPHY_FLAG_IBSS_RSN;
+       hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+       hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
+                                      REGULATORY_DISABLE_BEACON_HINTS;
 
        hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
        hw->wiphy->n_iface_combinations =
index dff7592e1ff84e5c3f6a05d673e2a39514cbb870..e0cd100b40cd6d5f69155d04fb2bcccd0d2c62a6 100644 (file)
@@ -192,7 +192,7 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
        for (i = 0; i < cmd->channel_count; i++) {
                chan->channel = cpu_to_le16(req->channels[i]->hw_value);
                chan->type = cpu_to_le32(type);
-               if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+               if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
                        chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
                chan->active_dwell = cpu_to_le16(active_dwell);
                chan->passive_dwell = cpu_to_le16(passive_dwell);
@@ -642,7 +642,7 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
                channels->iter_count[index] = cpu_to_le16(1);
                channels->iter_interval[index] = 0;
 
-               if (!(s_band->channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
+               if (!(s_band->channels[i].flags & IEEE80211_CHAN_NO_IR))
                        channels->type[index] |=
                                cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
 
index 991238afd1b60c04ae437fafeb7a108713ea3134..58c6ee5de98f9256b2e3db4735adbfe1fed299bd 100644 (file)
@@ -849,7 +849,7 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
                        card->started = true;
                        /* Tell PM core that we don't need the card to be
                         * powered now */
-                       pm_runtime_put_noidle(&func->dev);
+                       pm_runtime_put(&func->dev);
                }
        }
 
@@ -907,8 +907,8 @@ static int if_sdio_power_on(struct if_sdio_card *card)
        sdio_release_host(func);
        ret = if_sdio_prog_firmware(card);
        if (ret) {
-               sdio_disable_func(func);
-               return ret;
+               sdio_claim_host(func);
+               goto disable;
        }
 
        return 0;
index 83669151bb8242e31931735700eb27fe4cd01821..f11728a866ff3129b44e33ae6aa8597171c7005b 100644 (file)
@@ -93,7 +93,6 @@ static void free_if_spi_card(struct if_spi_card *card)
                list_del(&packet->list);
                kfree(packet);
        }
-       spi_set_drvdata(card->spi, NULL);
        kfree(card);
 }
 
index c72438bb2fafd24b8e59f416d4e4311752dce941..9c0cc8ded0216de43d09300dbed19cfa9fe2e3b3 100644 (file)
@@ -159,7 +159,7 @@ static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
        .reg_rules = {
                REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
                REG_RULE(5725-10, 5850+10, 40, 0, 30,
-                       NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
+                        NL80211_RRF_NO_IR),
        }
 };
 
@@ -353,7 +353,6 @@ struct mac80211_hwsim_data {
        } ps;
        bool ps_poll_pending;
        struct dentry *debugfs;
-       struct dentry *debugfs_ps;
 
        struct sk_buff_head pending;    /* packets pending */
        /*
@@ -362,7 +361,6 @@ struct mac80211_hwsim_data {
         * radio can be in more then one group.
         */
        u64 group;
-       struct dentry *debugfs_group;
 
        int power_level;
 
@@ -1493,7 +1491,7 @@ static void hw_scan_work(struct work_struct *work)
                    req->channels[hwsim->scan_chan_idx]->center_freq);
 
        hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx];
-       if (hwsim->tmp_chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
+       if (hwsim->tmp_chan->flags & IEEE80211_CHAN_NO_IR ||
            !req->n_ssids) {
                dwell = 120;
        } else {
@@ -1742,9 +1740,7 @@ static void mac80211_hwsim_free(void)
        spin_unlock_bh(&hwsim_radio_lock);
 
        list_for_each_entry_safe(data, tmpdata, &tmplist, list) {
-               debugfs_remove(data->debugfs_group);
-               debugfs_remove(data->debugfs_ps);
-               debugfs_remove(data->debugfs);
+               debugfs_remove_recursive(data->debugfs);
                ieee80211_unregister_hw(data->hw);
                device_release_driver(data->dev);
                device_unregister(data->dev);
@@ -1901,6 +1897,17 @@ static int hwsim_fops_ps_write(void *dat, u64 val)
 DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write,
                        "%llu\n");
 
+static int hwsim_write_simulate_radar(void *dat, u64 val)
+{
+       struct mac80211_hwsim_data *data = dat;
+
+       ieee80211_radar_detected(data->hw);
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(hwsim_simulate_radar, NULL,
+                       hwsim_write_simulate_radar, "%llu\n");
 
 static int hwsim_fops_group_read(void *dat, u64 *val)
 {
@@ -2201,11 +2208,28 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = {
        { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) },
 };
 
-static struct ieee80211_iface_combination hwsim_if_comb = {
-       .limits = hwsim_if_limits,
-       .n_limits = ARRAY_SIZE(hwsim_if_limits),
-       .max_interfaces = 2048,
-       .num_different_channels = 1,
+static const struct ieee80211_iface_limit hwsim_if_dfs_limits[] = {
+       { .max = 8, .types = BIT(NL80211_IFTYPE_AP) },
+};
+
+static struct ieee80211_iface_combination hwsim_if_comb[] = {
+       {
+               .limits = hwsim_if_limits,
+               .n_limits = ARRAY_SIZE(hwsim_if_limits),
+               .max_interfaces = 2048,
+               .num_different_channels = 1,
+       },
+       {
+               .limits = hwsim_if_dfs_limits,
+               .n_limits = ARRAY_SIZE(hwsim_if_dfs_limits),
+               .max_interfaces = 8,
+               .num_different_channels = 1,
+               .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
+                                      BIT(NL80211_CHAN_WIDTH_20) |
+                                      BIT(NL80211_CHAN_WIDTH_40) |
+                                      BIT(NL80211_CHAN_WIDTH_80) |
+                                      BIT(NL80211_CHAN_WIDTH_160),
+       }
 };
 
 static int __init init_mac80211_hwsim(void)
@@ -2223,7 +2247,7 @@ static int __init init_mac80211_hwsim(void)
                return -EINVAL;
 
        if (channels > 1) {
-               hwsim_if_comb.num_different_channels = channels;
+               hwsim_if_comb[0].num_different_channels = channels;
                mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan;
                mac80211_hwsim_ops.cancel_hw_scan =
                        mac80211_hwsim_cancel_hw_scan;
@@ -2303,13 +2327,15 @@ static int __init init_mac80211_hwsim(void)
                hw->wiphy->n_addresses = 2;
                hw->wiphy->addresses = data->addresses;
 
-               hw->wiphy->iface_combinations = &hwsim_if_comb;
-               hw->wiphy->n_iface_combinations = 1;
+               hw->wiphy->iface_combinations = hwsim_if_comb;
+               hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb);
 
                if (channels > 1) {
                        hw->wiphy->max_scan_ssids = 255;
                        hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
                        hw->wiphy->max_remain_on_channel_duration = 1000;
+                       /* For channels > 1 DFS is not allowed */
+                       hw->wiphy->n_iface_combinations = 1;
                }
 
                INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
@@ -2333,7 +2359,8 @@ static int __init init_mac80211_hwsim(void)
                            IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
                            IEEE80211_HW_AMPDU_AGGREGATION |
                            IEEE80211_HW_WANT_MONITOR_VIF |
-                           IEEE80211_HW_QUEUE_CONTROL;
+                           IEEE80211_HW_QUEUE_CONTROL |
+                           IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
                if (rctbl)
                        hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE;
 
@@ -2393,6 +2420,7 @@ static int __init init_mac80211_hwsim(void)
                        sband->vht_cap.cap =
                                IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
                                IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
+                               IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
                                IEEE80211_VHT_CAP_RXLDPC |
                                IEEE80211_VHT_CAP_SHORT_GI_80 |
                                IEEE80211_VHT_CAP_SHORT_GI_160 |
@@ -2435,46 +2463,53 @@ static int __init init_mac80211_hwsim(void)
                        break;
                case HWSIM_REGTEST_WORLD_ROAM:
                        if (i == 0) {
-                               hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+                               hw->wiphy->regulatory_flags |=
+                                       REGULATORY_CUSTOM_REG;
                                wiphy_apply_custom_regulatory(hw->wiphy,
                                        &hwsim_world_regdom_custom_01);
                        }
                        break;
                case HWSIM_REGTEST_CUSTOM_WORLD:
-                       hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+                       hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
                        wiphy_apply_custom_regulatory(hw->wiphy,
                                &hwsim_world_regdom_custom_01);
                        break;
                case HWSIM_REGTEST_CUSTOM_WORLD_2:
                        if (i == 0) {
-                               hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+                               hw->wiphy->regulatory_flags |=
+                                       REGULATORY_CUSTOM_REG;
                                wiphy_apply_custom_regulatory(hw->wiphy,
                                        &hwsim_world_regdom_custom_01);
                        } else if (i == 1) {
-                               hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+                               hw->wiphy->regulatory_flags |=
+                                       REGULATORY_CUSTOM_REG;
                                wiphy_apply_custom_regulatory(hw->wiphy,
                                        &hwsim_world_regdom_custom_02);
                        }
                        break;
                case HWSIM_REGTEST_STRICT_ALL:
-                       hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
+                       hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
                        break;
                case HWSIM_REGTEST_STRICT_FOLLOW:
                case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
                        if (i == 0)
-                               hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
+                               hw->wiphy->regulatory_flags |=
+                                       REGULATORY_STRICT_REG;
                        break;
                case HWSIM_REGTEST_ALL:
                        if (i == 0) {
-                               hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+                               hw->wiphy->regulatory_flags |=
+                                       REGULATORY_CUSTOM_REG;
                                wiphy_apply_custom_regulatory(hw->wiphy,
                                        &hwsim_world_regdom_custom_01);
                        } else if (i == 1) {
-                               hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+                               hw->wiphy->regulatory_flags |=
+                                       REGULATORY_CUSTOM_REG;
                                wiphy_apply_custom_regulatory(hw->wiphy,
                                        &hwsim_world_regdom_custom_02);
                        } else if (i == 4)
-                               hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
+                               hw->wiphy->regulatory_flags |=
+                                       REGULATORY_STRICT_REG;
                        break;
                default:
                        break;
@@ -2541,16 +2576,18 @@ static int __init init_mac80211_hwsim(void)
 
                data->debugfs = debugfs_create_dir("hwsim",
                                                   hw->wiphy->debugfsdir);
-               data->debugfs_ps = debugfs_create_file("ps", 0666,
-                                                      data->debugfs, data,
-                                                      &hwsim_fops_ps);
-               data->debugfs_group = debugfs_create_file("group", 0666,
-                                                       data->debugfs, data,
-                                                       &hwsim_fops_group);
+               debugfs_create_file("ps", 0666, data->debugfs, data,
+                                   &hwsim_fops_ps);
+               debugfs_create_file("group", 0666, data->debugfs, data,
+                                   &hwsim_fops_group);
+               if (channels == 1)
+                       debugfs_create_file("dfs_simulate_radar", 0222,
+                                           data->debugfs,
+                                           data, &hwsim_simulate_radar);
 
                tasklet_hrtimer_init(&data->beacon_timer,
                                     mac80211_hwsim_beacon,
-                                    CLOCK_REALTIME, HRTIMER_MODE_ABS);
+                                    CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
 
                list_add_tail(&data->list, &hwsim_radios);
        }
index aeaea0e3b4c414ae925b79a3eb4962f7bb36ad4b..d9b7330c902f1824a57cdc265df82590b16d3180 100644 (file)
@@ -50,24 +50,24 @@ static const struct ieee80211_regdomain mwifiex_world_regdom_custom = {
                REG_RULE(2412-10, 2462+10, 40, 3, 20, 0),
                /* Channel 12 - 13 */
                REG_RULE(2467-10, 2472+10, 20, 3, 20,
-                        NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
+                        NL80211_RRF_NO_IR),
                /* Channel 14 */
                REG_RULE(2484-10, 2484+10, 20, 3, 20,
-                        NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
+                        NL80211_RRF_NO_IR |
                         NL80211_RRF_NO_OFDM),
                /* Channel 36 - 48 */
                REG_RULE(5180-10, 5240+10, 40, 3, 20,
-                        NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
+                        NL80211_RRF_NO_IR),
                /* Channel 149 - 165 */
                REG_RULE(5745-10, 5825+10, 40, 3, 20,
-                        NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
+                        NL80211_RRF_NO_IR),
                /* Channel 52 - 64 */
                REG_RULE(5260-10, 5320+10, 40, 3, 30,
-                        NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
+                        NL80211_RRF_NO_IR |
                         NL80211_RRF_DFS),
                /* Channel 100 - 140 */
                REG_RULE(5500-10, 5700+10, 40, 3, 30,
-                        NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
+                        NL80211_RRF_NO_IR |
                         NL80211_RRF_DFS),
        }
 };
@@ -184,10 +184,10 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
  */
 static int
 mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
-                        struct ieee80211_channel *chan, bool offchan,
-                        unsigned int wait, const u8 *buf, size_t len,
-                        bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+                        struct cfg80211_mgmt_tx_params *params, u64 *cookie)
 {
+       const u8 *buf = params->buf;
+       size_t len = params->len;
        struct sk_buff *skb;
        u16 pkt_len;
        const struct ieee80211_mgmt *mgmt;
@@ -1968,7 +1968,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
                user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
                user_scan_cfg->chan_list[i].radio_type = chan->band;
 
-               if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+               if (chan->flags & IEEE80211_CHAN_NO_IR)
                        user_scan_cfg->chan_list[i].scan_type =
                                                MWIFIEX_SCAN_TYPE_PASSIVE;
                else
@@ -2702,9 +2702,10 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
        wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
                        WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
                        WIPHY_FLAG_AP_UAPSD |
-                       WIPHY_FLAG_CUSTOM_REGULATORY |
-                       WIPHY_FLAG_STRICT_REGULATORY |
                        WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+       wiphy->regulatory_flags |=
+                       REGULATORY_CUSTOM_REG |
+                       REGULATORY_STRICT_REG;
 
        wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
 
index 8cf7d50a7603121682c7f9a9684a64a978de85c9..0ed06646f19a1e9de631f8874b1cb236dce06340 100644 (file)
@@ -515,14 +515,14 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
                                scan_chan_list[chan_idx].max_scan_time =
                                        cpu_to_le16((u16) user_scan_in->
                                        chan_list[0].scan_time);
-                       else if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+                       else if (ch->flags & IEEE80211_CHAN_NO_IR)
                                scan_chan_list[chan_idx].max_scan_time =
                                        cpu_to_le16(adapter->passive_scan_time);
                        else
                                scan_chan_list[chan_idx].max_scan_time =
                                        cpu_to_le16(adapter->active_scan_time);
 
-                       if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+                       if (ch->flags & IEEE80211_CHAN_NO_IR)
                                scan_chan_list[chan_idx].chan_scan_mode_bitmap
                                        |= MWIFIEX_PASSIVE_SCAN;
                        else
index 2675ca7f8d146ca579a7a4bb4c1397f641a95ee0..551194605aa7ae1862c2df113b33a8701c8d5243 100644 (file)
@@ -338,8 +338,7 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
        if (!data_buf)
                return -1;
 
-       pg_tlv_hdr = (struct mwifiex_types_power_group *)
-               ((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg));
+       pg_tlv_hdr = (struct mwifiex_types_power_group *)((u8 *)data_buf);
        pg = (struct mwifiex_power_group *)
                ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group));
        length = le16_to_cpu(pg_tlv_hdr->length);
@@ -383,19 +382,25 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
        struct mwifiex_types_power_group *pg_tlv_hdr;
        struct mwifiex_power_group *pg;
        u16 action = le16_to_cpu(txp_cfg->action);
+       u16 tlv_buf_left;
 
-       switch (action) {
-       case HostCmd_ACT_GEN_GET:
-               pg_tlv_hdr = (struct mwifiex_types_power_group *)
-                       ((u8 *) txp_cfg +
-                        sizeof(struct host_cmd_ds_txpwr_cfg));
+       pg_tlv_hdr = (struct mwifiex_types_power_group *)
+               ((u8 *)txp_cfg +
+                sizeof(struct host_cmd_ds_txpwr_cfg));
 
-               pg = (struct mwifiex_power_group *)
-                       ((u8 *) pg_tlv_hdr +
-                        sizeof(struct mwifiex_types_power_group));
+       pg = (struct mwifiex_power_group *)
+               ((u8 *)pg_tlv_hdr +
+                sizeof(struct mwifiex_types_power_group));
 
+       tlv_buf_left = le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*txp_cfg);
+       if (tlv_buf_left <
+                       le16_to_cpu(pg_tlv_hdr->length) + sizeof(*pg_tlv_hdr))
+               return 0;
+
+       switch (action) {
+       case HostCmd_ACT_GEN_GET:
                if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
-                       mwifiex_get_power_level(priv, txp_cfg);
+                       mwifiex_get_power_level(priv, pg_tlv_hdr);
 
                priv->tx_power_level = (u16) pg->power_min;
                break;
@@ -404,14 +409,6 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
                if (!le32_to_cpu(txp_cfg->mode))
                        break;
 
-               pg_tlv_hdr = (struct mwifiex_types_power_group *)
-                       ((u8 *) txp_cfg +
-                        sizeof(struct host_cmd_ds_txpwr_cfg));
-
-               pg = (struct mwifiex_power_group *)
-                       ((u8 *) pg_tlv_hdr +
-                        sizeof(struct mwifiex_types_power_group));
-
                if (pg->power_max == pg->power_min)
                        priv->tx_power_level = (u16) pg->power_min;
                break;
index e05d9b4c8317c44df17b9ca0c2dea0577741b1a6..7fa2898d06192615e4a9524a669fc987d141d24f 100644 (file)
@@ -914,7 +914,6 @@ islpci_setup(struct pci_dev *pdev)
       do_islpci_free_memory:
        islpci_free_memory(priv);
       do_free_netdev:
-       pci_set_drvdata(pdev, NULL);
        free_netdev(ndev);
        priv = NULL;
        return NULL;
index 9e68e0cb718ee0dfff1e00066aef36f1c04e0e15..d7b9e6376424d8153d87ec9862eea1d671185004 100644 (file)
@@ -199,7 +199,6 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
       do_unregister_netdev:
        unregister_netdev(ndev);
        islpci_free_memory(priv);
-       pci_set_drvdata(pdev, NULL);
        free_netdev(ndev);
        priv = NULL;
       do_pci_clear_mwi:
@@ -247,7 +246,6 @@ prism54_remove(struct pci_dev *pdev)
        /* free the PCI memory and unmap the remapped page */
        islpci_free_memory(priv);
 
-       pci_set_drvdata(pdev, NULL);
        free_netdev(ndev);
        priv = NULL;
 
index 776aff3678ff23bddda925dfbb48bde925cb7b82..5ee5b296ad28fceb720cbd7a3016b57beaa7ed2f 100644 (file)
@@ -5462,15 +5462,14 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
 
        rt2800_bbp_write(rt2x00dev, 68, 0x0b);
 
-       rt2800_bbp_write(rt2x00dev, 69, 0x12);
+       rt2800_bbp_write(rt2x00dev, 69, 0x0d);
+       rt2800_bbp_write(rt2x00dev, 70, 0x06);
        rt2800_bbp_write(rt2x00dev, 73, 0x13);
        rt2800_bbp_write(rt2x00dev, 75, 0x46);
        rt2800_bbp_write(rt2x00dev, 76, 0x28);
 
        rt2800_bbp_write(rt2x00dev, 77, 0x59);
 
-       rt2800_bbp_write(rt2x00dev, 70, 0x0a);
-
        rt2800_bbp_write(rt2x00dev, 79, 0x13);
        rt2800_bbp_write(rt2x00dev, 80, 0x05);
        rt2800_bbp_write(rt2x00dev, 81, 0x33);
@@ -5513,6 +5512,7 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
        if (rt2x00_rt(rt2x00dev, RT5392)) {
                rt2800_bbp_write(rt2x00dev, 134, 0xd0);
                rt2800_bbp_write(rt2x00dev, 135, 0xf6);
+               rt2800_bbp_write(rt2x00dev, 148, 0x84);
        }
 
        rt2800_disable_unused_dac_adc(rt2x00dev);
@@ -6453,7 +6453,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
        rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
        rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
        rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
-       rt2800_rfcsr_write(rt2x00dev, 12, 0xc6);
+       rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
        rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
        rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
        rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
@@ -6466,7 +6466,8 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
        rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
        rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
        rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
-       if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
+       if (rt2x00_is_usb(rt2x00dev) &&
+           rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
                rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
        else
                rt2800_rfcsr_write(rt2x00dev, 25, 0xc0);
@@ -6486,10 +6487,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
        rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
        rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
 
-       if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
-               rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
-       else
-               rt2800_rfcsr_write(rt2x00dev, 40, 0x4b);
+       rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
        rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
        rt2800_rfcsr_write(rt2x00dev, 42, 0xd2);
        rt2800_rfcsr_write(rt2x00dev, 43, 0x9a);
@@ -6510,16 +6508,26 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
                rt2800_rfcsr_write(rt2x00dev, 53, 0x84);
        rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
        rt2800_rfcsr_write(rt2x00dev, 55, 0x44);
-       rt2800_rfcsr_write(rt2x00dev, 56, 0x22);
+       if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
+               rt2800_rfcsr_write(rt2x00dev, 56, 0x42);
+       else
+               rt2800_rfcsr_write(rt2x00dev, 56, 0x22);
        rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
        rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
        rt2800_rfcsr_write(rt2x00dev, 59, 0x8f);
 
        rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
-       if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
-               rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
-       else
-               rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
+       if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
+               if (rt2x00_is_usb(rt2x00dev))
+                       rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
+               else
+                       rt2800_rfcsr_write(rt2x00dev, 61, 0xd5);
+       } else {
+               if (rt2x00_is_usb(rt2x00dev))
+                       rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
+               else
+                       rt2800_rfcsr_write(rt2x00dev, 61, 0xb5);
+       }
        rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
        rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
 
@@ -6602,7 +6610,6 @@ static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev)
 
        rt2800_rfcsr_write(rt2x00dev, 1, 0x3F);
        rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
-       rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
        rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
        rt2800_rfcsr_write(rt2x00dev, 6, 0xE4);
        rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
index 25da20e7e1f34ab2c0b1fd3e38a82d1faece0f9e..af721831dcbc902af12cf872857b8a4134d6b086 100644 (file)
@@ -156,8 +156,6 @@ exit_release_regions:
 exit_disable_device:
        pci_disable_device(pci_dev);
 
-       pci_set_drvdata(pci_dev, NULL);
-
        return retval;
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_probe);
@@ -177,7 +175,6 @@ void rt2x00pci_remove(struct pci_dev *pci_dev)
        /*
         * Free the PCI device data.
         */
-       pci_set_drvdata(pci_dev, NULL);
        pci_disable_device(pci_dev);
        pci_release_regions(pci_dev);
 }
index 9a6edb0c014ec3526c5b4c260b8784cc8fd855d0..ec9aa5b6738171f547dc50a45b977795de133486 100644 (file)
@@ -416,7 +416,7 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
        struct rtl8187_rx_info *info;
        int ret = 0;
 
-       while (skb_queue_len(&priv->rx_queue) < 16) {
+       while (skb_queue_len(&priv->rx_queue) < 32) {
                skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
                if (!skb) {
                        ret = -ENOMEM;
index ff784072fb4233a29a46a55bf21d75e094bb8d5c..fcf9b621918c07ba2ab42e38622af9b56ac66682 100644 (file)
@@ -1437,7 +1437,8 @@ void rtl_watchdog_wq_callback(void *data)
                        /* if we can't recv beacon for 6s, we should
                         * reconnect this AP
                         */
-                       if (rtlpriv->link_info.roam_times >= 3) {
+                       if ((rtlpriv->link_info.roam_times >= 3) &&
+                           !is_zero_ether_addr(rtlpriv->mac80211.bssid)) {
                                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
                                         "AP off, try to reconnect now\n");
                                rtlpriv->link_info.roam_times = 0;
index 210ce7cd94d8d14201a68ce285e9c880993d30db..2d337a0c3df027c86742af4367c0c00fe64d2f49 100644 (file)
@@ -46,10 +46,20 @@ void rtl_fw_cb(const struct firmware *firmware, void *context)
                         "Firmware callback routine entered!\n");
        complete(&rtlpriv->firmware_loading_complete);
        if (!firmware) {
+               if (rtlpriv->cfg->alt_fw_name) {
+                       err = request_firmware(&firmware,
+                                              rtlpriv->cfg->alt_fw_name,
+                                              rtlpriv->io.dev);
+                       pr_info("Loading alternative firmware %s\n",
+                               rtlpriv->cfg->alt_fw_name);
+                       if (!err)
+                               goto found_alt;
+               }
                pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
                rtlpriv->max_fw_size = 0;
                return;
        }
+found_alt:
        if (firmware->size > rtlpriv->max_fw_size) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
                         "Firmware is too big!\n");
@@ -184,6 +194,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
                                        rtlpriv->cfg->maps
                                        [RTL_IBSS_INT_MASKS]);
                }
+               mac->link_state = MAC80211_LINKED;
                break;
        case NL80211_IFTYPE_ADHOC:
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
index 0f494444bcd1d90b457b927d704bf77abe0592ca..8707d1a94995c740d11a5b6cd3dd5d4849616f53 100644 (file)
@@ -688,8 +688,6 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb,
                rtlpriv->stats.rxbytesunicast += skb->len;
        }
 
-       rtl_is_special_data(hw, skb, false);
-
        if (ieee80211_is_data(fc)) {
                rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
 
index d7d0d4948b01f2e804e6bcddfca93b10c7cdb312..a4eb9b271438657e863dc07af8d9ca20ac431301 100644 (file)
@@ -59,30 +59,26 @@ static struct country_code_to_enum_rd allCountries[] = {
  */
 #define RTL819x_2GHZ_CH12_13   \
        REG_RULE(2467-10, 2472+10, 40, 0, 20,\
-       NL80211_RRF_PASSIVE_SCAN)
+                NL80211_RRF_NO_IR)
 
 #define RTL819x_2GHZ_CH14      \
        REG_RULE(2484-10, 2484+10, 40, 0, 20, \
-       NL80211_RRF_PASSIVE_SCAN | \
-       NL80211_RRF_NO_OFDM)
+                NL80211_RRF_NO_IR | NL80211_RRF_NO_OFDM)
 
 /* 5G chan 36 - chan 64*/
 #define RTL819x_5GHZ_5150_5350 \
        REG_RULE(5150-10, 5350+10, 40, 0, 30, \
-       NL80211_RRF_PASSIVE_SCAN | \
-       NL80211_RRF_NO_IBSS)
+                NL80211_RRF_NO_IR)
 
 /* 5G chan 100 - chan 165*/
 #define RTL819x_5GHZ_5470_5850 \
        REG_RULE(5470-10, 5850+10, 40, 0, 30, \
-       NL80211_RRF_PASSIVE_SCAN | \
-       NL80211_RRF_NO_IBSS)
+                NL80211_RRF_NO_IR)
 
 /* 5G chan 149 - chan 165*/
 #define RTL819x_5GHZ_5725_5850 \
        REG_RULE(5725-10, 5850+10, 40, 0, 30, \
-       NL80211_RRF_PASSIVE_SCAN | \
-       NL80211_RRF_NO_IBSS)
+                NL80211_RRF_NO_IR)
 
 #define RTL819x_5GHZ_ALL       \
        (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850)
@@ -172,7 +168,8 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
                            (ch->flags & IEEE80211_CHAN_RADAR))
                                continue;
                        if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
-                               reg_rule = freq_reg_info(wiphy, ch->center_freq);
+                               reg_rule = freq_reg_info(wiphy,
+                                                        MHZ_TO_KHZ(ch->center_freq));
                                if (IS_ERR(reg_rule))
                                        continue;
 
@@ -185,16 +182,11 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
                                 *regulatory_hint().
                                 */
 
-                               if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
-                                       ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
-                               if (!(reg_rule->
-                                    flags & NL80211_RRF_PASSIVE_SCAN))
-                                       ch->flags &=
-                                           ~IEEE80211_CHAN_PASSIVE_SCAN;
+                               if (!(reg_rule->flags & NL80211_RRF_NO_IR))
+                                       ch->flags &= ~IEEE80211_CHAN_NO_IR;
                        } else {
                                if (ch->beacon_found)
-                                       ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
-                                                 IEEE80211_CHAN_PASSIVE_SCAN);
+                                       ch->flags &= ~IEEE80211_CHAN_NO_IR;
                        }
                }
        }
@@ -219,11 +211,11 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
         */
        if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
                ch = &sband->channels[11];      /* CH 12 */
-               if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                       ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+               if (ch->flags & IEEE80211_CHAN_NO_IR)
+                       ch->flags &= ~IEEE80211_CHAN_NO_IR;
                ch = &sband->channels[12];      /* CH 13 */
-               if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                       ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+               if (ch->flags & IEEE80211_CHAN_NO_IR)
+                       ch->flags &= ~IEEE80211_CHAN_NO_IR;
                return;
        }
 
@@ -235,19 +227,19 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
         */
 
        ch = &sband->channels[11];      /* CH 12 */
-       reg_rule = freq_reg_info(wiphy, ch->center_freq);
+       reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
        if (!IS_ERR(reg_rule)) {
-               if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
-                       if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                               ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+               if (!(reg_rule->flags & NL80211_RRF_NO_IR))
+                       if (ch->flags & IEEE80211_CHAN_NO_IR)
+                               ch->flags &= ~IEEE80211_CHAN_NO_IR;
        }
 
        ch = &sband->channels[12];      /* CH 13 */
-       reg_rule = freq_reg_info(wiphy, ch->center_freq);
+       reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
        if (!IS_ERR(reg_rule)) {
-               if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
-                       if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                               ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+               if (!(reg_rule->flags & NL80211_RRF_NO_IR))
+                       if (ch->flags & IEEE80211_CHAN_NO_IR)
+                               ch->flags &= ~IEEE80211_CHAN_NO_IR;
        }
 }
 
@@ -284,8 +276,7 @@ static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy)
                 */
                if (!(ch->flags & IEEE80211_CHAN_DISABLED))
                        ch->flags |= IEEE80211_CHAN_RADAR |
-                           IEEE80211_CHAN_NO_IBSS |
-                           IEEE80211_CHAN_PASSIVE_SCAN;
+                                    IEEE80211_CHAN_NO_IR;
        }
 }
 
@@ -354,9 +345,9 @@ static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
 
        wiphy->reg_notifier = reg_notifier;
 
-       wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
-       wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;
-       wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;
+       wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
+       wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
+       wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
 
        regd = _rtl_regdomain_select(reg);
        wiphy_apply_custom_regulatory(wiphy, regd);
index 21a5cf060677494106afced5c7e8907dfcf86f3d..a6184b6e1d57ff50bca6a4f4aa16ac2871dc295f 100644 (file)
@@ -1078,7 +1078,7 @@ static void rtl88e_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
                                rtldm->swing_flag_ofdm = true;
                        }
 
-                       if (rtldm->swing_idx_cck != rtldm->swing_idx_cck) {
+                       if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) {
                                rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck;
                                rtldm->swing_flag_cck = true;
                        }
index e9caa5d4cff0f910488cd4b22899ad9b5c84665a..fd7e4a7c94dea1d4ad1e59d79c0633340964b8a7 100644 (file)
@@ -158,6 +158,42 @@ static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
        {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
 };
 
+static u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a};
+
+void dm_restorepowerindex(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8      index;
+
+       for (index = 0; index < 6; index++)
+               rtl_write_byte(rtlpriv, power_index_reg[index],
+                              rtlpriv->dm.powerindex_backup[index]);
+}
+EXPORT_SYMBOL_GPL(dm_restorepowerindex);
+
+void dm_writepowerindex(struct ieee80211_hw *hw, u8 value)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 index;
+
+       for (index = 0; index < 6; index++)
+               rtl_write_byte(rtlpriv, power_index_reg[index], value);
+}
+EXPORT_SYMBOL_GPL(dm_writepowerindex);
+
+void dm_savepowerindex(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 index;
+       u8 tmp;
+
+       for (index = 0; index < 6; index++) {
+               tmp = rtl_read_byte(rtlpriv, power_index_reg[index]);
+               rtlpriv->dm.powerindex_backup[index] = tmp;
+       }
+}
+EXPORT_SYMBOL_GPL(dm_savepowerindex);
+
 static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -180,7 +216,12 @@ static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
        dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
        dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
        dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
-       dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
+       dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LowRssi;
+
+       dm_digtable->forbidden_igi = DM_DIG_MIN;
+       dm_digtable->large_fa_hit = 0;
+       dm_digtable->recover_cnt = 0;
+       dm_digtable->dig_dynamic_min  = 0x25;
 }
 
 static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
@@ -206,7 +247,9 @@ static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
                rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
        }
 
-       return (u8) rssi_val_min;
+       if (rssi_val_min > 100)
+               rssi_val_min = 100;
+       return (u8)rssi_val_min;
 }
 
 static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
@@ -224,9 +267,17 @@ static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
 
        ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
        falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
+
+        ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
+       falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
+       falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
+
        falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
-           falsealm_cnt->cnt_rate_illegal +
-           falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
+                                     falsealm_cnt->cnt_rate_illegal +
+                                     falsealm_cnt->cnt_crc8_fail +
+                                     falsealm_cnt->cnt_mcs_fail +
+                                     falsealm_cnt->cnt_fast_fsync_fail +
+                                     falsealm_cnt->cnt_sb_search_fail;
 
        rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
        ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
@@ -271,12 +322,14 @@ static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
                value_igi++;
        else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
                value_igi += 2;
+
        if (value_igi > DM_DIG_FA_UPPER)
                value_igi = DM_DIG_FA_UPPER;
        else if (value_igi < DM_DIG_FA_LOWER)
                value_igi = DM_DIG_FA_LOWER;
+
        if (rtlpriv->falsealm_cnt.cnt_all > 10000)
-               value_igi = 0x32;
+               value_igi = DM_DIG_FA_UPPER;
 
        dm_digtable->cur_igvalue = value_igi;
        rtl92c_dm_write_dig(hw);
@@ -286,32 +339,80 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct dig_t *digtable = &rtlpriv->dm_digtable;
+       u32 isbt;
+
+       /* modify DIG lower bound, deal with abnorally large false alarm */
+       if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
+               digtable->large_fa_hit++;
+               if (digtable->forbidden_igi < digtable->cur_igvalue) {
+                       digtable->forbidden_igi = digtable->cur_igvalue;
+                       digtable->large_fa_hit = 1;
+               }
 
-       if (rtlpriv->falsealm_cnt.cnt_all > digtable->fa_highthresh) {
-               if ((digtable->back_val - 2) < digtable->back_range_min)
-                       digtable->back_val = digtable->back_range_min;
-               else
-                       digtable->back_val -= 2;
-       } else if (rtlpriv->falsealm_cnt.cnt_all < digtable->fa_lowthresh) {
-               if ((digtable->back_val + 2) > digtable->back_range_max)
-                       digtable->back_val = digtable->back_range_max;
-               else
-                       digtable->back_val += 2;
+               if (digtable->large_fa_hit >= 3) {
+                       if ((digtable->forbidden_igi + 1) >
+                           digtable->rx_gain_max)
+                               digtable->rx_gain_min = digtable->rx_gain_max;
+                       else
+                               digtable->rx_gain_min = (digtable->forbidden_igi + 1);
+                       digtable->recover_cnt = 3600; /* 3600=2hr */
+               }
+       } else {
+               /* Recovery mechanism for IGI lower bound */
+               if (digtable->recover_cnt != 0) {
+                       digtable->recover_cnt--;
+               } else {
+                       if (digtable->large_fa_hit == 0) {
+                               if ((digtable->forbidden_igi-1) < DM_DIG_MIN) {
+                                       digtable->forbidden_igi = DM_DIG_MIN;
+                                       digtable->rx_gain_min = DM_DIG_MIN;
+                               } else {
+                                       digtable->forbidden_igi--;
+                                       digtable->rx_gain_min = digtable->forbidden_igi + 1;
+                               }
+                       } else if (digtable->large_fa_hit == 3) {
+                               digtable->large_fa_hit = 0;
+                       }
+               }
+       }
+       if (rtlpriv->falsealm_cnt.cnt_all < 250) {
+               isbt = rtl_read_byte(rtlpriv, 0x4fd) & 0x01;
+
+               if (!isbt) {
+                       if (rtlpriv->falsealm_cnt.cnt_all >
+                           digtable->fa_lowthresh) {
+                               if ((digtable->back_val - 2) <
+                                  digtable->back_range_min)
+                                       digtable->back_val = digtable->back_range_min;
+                               else
+                                       digtable->back_val -= 2;
+                       } else if (rtlpriv->falsealm_cnt.cnt_all <
+                                  digtable->fa_lowthresh) {
+                               if ((digtable->back_val + 2) >
+                                   digtable->back_range_max)
+                                       digtable->back_val = digtable->back_range_max;
+                               else
+                                       digtable->back_val += 2;
+                       }
+               } else {
+                       digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
+               }
+       } else {
+               /* Adjust initial gain by false alarm */
+               if (rtlpriv->falsealm_cnt.cnt_all > 1000)
+                       digtable->cur_igvalue = digtable->pre_igvalue + 2;
+               else if (rtlpriv->falsealm_cnt.cnt_all > 750)
+                       digtable->cur_igvalue = digtable->pre_igvalue + 1;
+               else if (rtlpriv->falsealm_cnt.cnt_all < 500)
+                       digtable->cur_igvalue = digtable->pre_igvalue - 1;
        }
 
-       if ((digtable->rssi_val_min + 10 - digtable->back_val) >
-           digtable->rx_gain_max)
+       /* Check initial gain by upper/lower bound */
+       if (digtable->cur_igvalue > digtable->rx_gain_max)
                digtable->cur_igvalue = digtable->rx_gain_max;
-       else if ((digtable->rssi_val_min + 10 -
-                 digtable->back_val) < digtable->rx_gain_min)
-               digtable->cur_igvalue = digtable->rx_gain_min;
-       else
-               digtable->cur_igvalue = digtable->rssi_val_min + 10 -
-                   digtable->back_val;
 
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-                "rssi_val_min = %x back_val %x\n",
-                digtable->rssi_val_min, digtable->back_val);
+       if (digtable->cur_igvalue < digtable->rx_gain_min)
+               digtable->cur_igvalue = digtable->rx_gain_min;
 
        rtl92c_dm_write_dig(hw);
 }
@@ -329,7 +430,7 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
                multi_sta = true;
 
        if (!multi_sta ||
-           dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
+           dm_digtable->cursta_cstate == DIG_STA_DISCONNECT) {
                initialized = false;
                dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
                return;
@@ -375,7 +476,6 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
                 "presta_cstate = %x, cursta_cstate = %x\n",
                 dm_digtable->presta_cstate, dm_digtable->cursta_cstate);
-
        if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
            dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
            dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
@@ -383,6 +483,8 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
                if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
                        dm_digtable->rssi_val_min =
                            rtl92c_dm_initial_gain_min_pwdb(hw);
+                       if (dm_digtable->rssi_val_min > 100)
+                               dm_digtable->rssi_val_min = 100;
                        rtl92c_dm_ctrl_initgain_by_rssi(hw);
                }
        } else {
@@ -398,11 +500,12 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
 static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
-       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 
        if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
                dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw);
+               if (dm_digtable->rssi_val_min > 100)
+                       dm_digtable->rssi_val_min = 100;
 
                if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {
                        if (dm_digtable->rssi_val_min <= 25)
@@ -424,48 +527,14 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
        }
 
        if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
-               if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) {
-                       if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
-                               dm_digtable->cur_cck_fa_state =
-                                   CCK_FA_STAGE_High;
-                       else
-                               dm_digtable->cur_cck_fa_state = CCK_FA_STAGE_Low;
-
-                       if (dm_digtable->pre_cck_fa_state !=
-                           dm_digtable->cur_cck_fa_state) {
-                               if (dm_digtable->cur_cck_fa_state ==
-                                   CCK_FA_STAGE_Low)
-                                       rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
-                                                     0x83);
-                               else
-                                       rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
-                                                     0xcd);
-
-                               dm_digtable->pre_cck_fa_state =
-                                   dm_digtable->cur_cck_fa_state;
-                       }
-
-                       rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
-
-                       if (IS_92C_SERIAL(rtlhal->version))
-                               rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
-                                             MASKBYTE2, 0xd7);
-               } else {
+               if ((dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) ||
+                   (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_MAX))
+                       rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83);
+               else
                        rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
-                       rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
 
-                       if (IS_92C_SERIAL(rtlhal->version))
-                               rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
-                                             MASKBYTE2, 0xd3);
-               }
                dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
        }
-
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "CCKPDStage=%x\n",
-                dm_digtable->cur_cck_pd_state);
-
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "is92C=%x\n",
-                IS_92C_SERIAL(rtlhal->version));
 }
 
 static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
@@ -482,6 +551,8 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
        else
                dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
 
+       dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
+
        rtl92c_dm_initial_gain_sta(hw);
        rtl92c_dm_initial_gain_multi_sta(hw);
        rtl92c_dm_cck_packet_detection_thresh(hw);
@@ -493,23 +564,26 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
 static void rtl92c_dm_dig(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
-       struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 
        if (rtlpriv->dm.dm_initialgain_enable == false)
                return;
-       if (dm_digtable->dig_enable_flag == false)
+       if (!rtlpriv->dm.dm_flag & DYNAMIC_FUNC_DIG)
                return;
 
        rtl92c_dm_ctrl_initgain_by_twoport(hw);
-
 }
 
 static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-       rtlpriv->dm.dynamic_txpower_enable = false;
-
+       if (rtlpriv->rtlhal.interface == INTF_USB &&
+           rtlpriv->rtlhal.board_type & 0x1) {
+               dm_savepowerindex(hw);
+               rtlpriv->dm.dynamic_txpower_enable = true;
+       } else {
+               rtlpriv->dm.dynamic_txpower_enable = false;
+       }
        rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
        rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 }
@@ -524,9 +598,14 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
                 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
                 dm_digtable->back_val);
 
-       dm_digtable->cur_igvalue += 2;
-       if (dm_digtable->cur_igvalue > 0x3f)
-               dm_digtable->cur_igvalue = 0x3f;
+       if (rtlpriv->rtlhal.interface == INTF_USB &&
+           !dm_digtable->dig_enable_flag) {
+               dm_digtable->pre_igvalue = 0x17;
+               return;
+       }
+       dm_digtable->cur_igvalue -= 1;
+       if (dm_digtable->cur_igvalue < DM_DIG_MIN)
+               dm_digtable->cur_igvalue = DM_DIG_MIN;
 
        if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
                rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
@@ -536,11 +615,47 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
 
                dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
        }
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_WARNING,
+                "dig values 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+                dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
+                dm_digtable->rssi_val_min, dm_digtable->back_val,
+                dm_digtable->rx_gain_max, dm_digtable->rx_gain_min,
+                dm_digtable->large_fa_hit, dm_digtable->forbidden_igi);
 }
 EXPORT_SYMBOL(rtl92c_dm_write_dig);
 
 static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw)
 {
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff;
+
+       if (mac->link_state != MAC80211_LINKED)
+               return;
+
+       if (mac->opmode == NL80211_IFTYPE_ADHOC ||
+           mac->opmode == NL80211_IFTYPE_AP) {
+               /* TODO: Handle ADHOC and AP Mode */
+       }
+
+       if (tmpentry_max_pwdb != 0)
+               rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb;
+       else
+               rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
+
+       if (tmpentry_min_pwdb != 0xff)
+               rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb;
+       else
+               rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
+
+/* TODO:
+ *     if (mac->opmode == NL80211_IFTYPE_STATION) {
+ *             if (rtlpriv->rtlhal.fw_ready) {
+ *                     u32 param = (u32)(rtlpriv->dm.undec_sm_pwdb << 16);
+ *                     rtl8192c_set_rssi_cmd(hw, param);
+ *             }
+ *     }
+ */
 }
 
 void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw)
@@ -750,6 +865,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
                                rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
                        rtlpriv->dm.cck_index = cck_index_old;
                }
+               /* Handle USB High PA boards */
 
                delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
                    (thermalvalue - rtlpriv->dm.thermalvalue) :
@@ -1140,22 +1256,22 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
-       static u8 initialize;
-       static u32 reg_874, reg_c70, reg_85c, reg_a74;
 
-       if (initialize == 0) {
-               reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
-                                        MASKDWORD) & 0x1CC000) >> 14;
+       if (!rtlpriv->reg_init) {
+               rtlpriv->reg_874 = (rtl_get_bbreg(hw,
+                                                 RFPGA0_XCD_RFINTERFACESW,
+                                                 MASKDWORD) & 0x1CC000) >> 14;
 
-               reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
-                                        MASKDWORD) & BIT(3)) >> 3;
+               rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
+                                   MASKDWORD) & BIT(3)) >> 3;
 
-               reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
-                                        MASKDWORD) & 0xFF000000) >> 24;
+               rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
+                                   MASKDWORD) & 0xFF000000) >> 24;
 
-               reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12;
+               rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) &
+                                   0xF000) >> 12;
 
-               initialize = 1;
+               rtlpriv->reg_init = true;
        }
 
        if (!bforce_in_normal) {
@@ -1192,12 +1308,12 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
                        rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
                } else {
                        rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
-                                     0x1CC000, reg_874);
+                                     0x1CC000, rtlpriv->reg_874);
                        rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
-                                     reg_c70);
+                                     rtlpriv->reg_c70);
                        rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
-                                     reg_85c);
-                       rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74);
+                                     rtlpriv->reg_85c);
+                       rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74);
                        rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
                }
 
@@ -1213,6 +1329,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
+       /* Determine the minimum RSSI */
        if (((mac->link_state == MAC80211_NOLINK)) &&
            (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
                dm_pstable->rssi_val_min = 0;
@@ -1241,6 +1358,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
                         dm_pstable->rssi_val_min);
        }
 
+       /* Power Saving for 92C */
        if (IS_92C_SERIAL(rtlhal->version))
                ;/* rtl92c_dm_1r_cca(hw); */
        else
@@ -1252,12 +1370,23 @@ void rtl92c_dm_init(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
        rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
+       rtlpriv->dm.dm_flag = DYNAMIC_FUNC_DISABLE | DYNAMIC_FUNC_DIG;
+       rtlpriv->dm.undec_sm_pwdb = -1;
+       rtlpriv->dm.undec_sm_cck = -1;
+       rtlpriv->dm.dm_initialgain_enable = true;
        rtl92c_dm_diginit(hw);
+
+       rtlpriv->dm.dm_flag |= HAL_DM_HIPWR_DISABLE;
        rtl92c_dm_init_dynamic_txpower(hw);
+
        rtl92c_dm_init_edca_turbo(hw);
        rtl92c_dm_init_rate_adaptive_mask(hw);
+       rtlpriv->dm.dm_flag |= DYNAMIC_FUNC_SS;
        rtl92c_dm_initialize_txpower_tracking(hw);
        rtl92c_dm_init_dynamic_bb_powersaving(hw);
+
+       rtlpriv->dm.ofdm_pkt_cnt = 0;
+       rtlpriv->dm.dm_rssi_sel = RSSI_DEFAULT;
 }
 EXPORT_SYMBOL(rtl92c_dm_init);
 
@@ -1308,7 +1437,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
        }
 
        if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
-               rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
+               rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2;
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
                         "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
        } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
@@ -1328,8 +1457,16 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
                         "PHY_SetTxPowerLevel8192S() Channel = %d\n",
                         rtlphy->current_channel);
                rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
+               if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+                   TXHIGHPWRLEVEL_NORMAL)
+                       dm_restorepowerindex(hw);
+               else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+                        TXHIGHPWRLEVEL_LEVEL1)
+                       dm_writepowerindex(hw, 0x14);
+               else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+                        TXHIGHPWRLEVEL_LEVEL2)
+                       dm_writepowerindex(hw, 0x10);
        }
-
        rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
 }
 
@@ -1400,12 +1537,6 @@ u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw)
        else
                curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW);
 
-       /* Set Tx Power according to BT status. */
-       if (undec_sm_pwdb >= 30)
-               curr_bt_rssi_state |=  BT_RSSI_STATE_TXPOWER_LOW;
-       else if (undec_sm_pwdb < 25)
-               curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW);
-
        /* Check BT state related to BT_Idle in B/G mode. */
        if (undec_sm_pwdb < 15)
                curr_bt_rssi_state |=  BT_RSSI_STATE_BG_EDCA_LOW;
index 518e208c018064049406a0b653cdd5763d601440..4f232a063636ee01aa137efffca38b0dcc034b21 100644 (file)
 #define TX_POWER_NEAR_FIELD_THRESH_LVL2                74
 #define TX_POWER_NEAR_FIELD_THRESH_LVL1                67
 
+#define DYNAMIC_FUNC_DISABLE                   0x0
+#define DYNAMIC_FUNC_DIG                       BIT(0)
+#define DYNAMIC_FUNC_HP                                BIT(1)
+#define DYNAMIC_FUNC_SS                                BIT(2) /*Tx Power Tracking*/
+#define DYNAMIC_FUNC_BT                                BIT(3)
+#define DYNAMIC_FUNC_ANT_DIV                   BIT(4)
+
+#define        RSSI_CCK                                0
+#define        RSSI_OFDM                               1
+#define        RSSI_DEFAULT                            2
+
 struct swat_t {
        u8 failure_cnt;
        u8 try_flag;
@@ -167,5 +178,8 @@ void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
 void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);
 void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw);
 void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);
+void dm_savepowerindex(struct ieee80211_hw *hw);
+void dm_writepowerindex(struct ieee80211_hw *hw, u8 value);
+void dm_restorepowerindex(struct ieee80211_hw *hw);
 
 #endif
index 0c0e78263a665190aacf3d33d21fa87b99d4dd86..9e32ac8a4425f5dd9b9d3c8f4c57db66d684c1dd 100644 (file)
@@ -1147,6 +1147,12 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
                0x522, 0x550, 0x551, 0x040
        };
 
+       u32 iqk_bb_reg_92C[9] = {
+               0xc04, 0xc08, 0x874, 0xb68,
+               0xb6c, 0x870, 0x860, 0x864,
+               0x800
+       };
+
        const u32 retrycount = 2;
 
        if (t == 0) {
@@ -1157,6 +1163,8 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
                                                rtlphy->adda_backup, 16);
                _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,
                                               rtlphy->iqk_mac_backup);
+               _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg_92C,
+                                               rtlphy->iqk_bb_backup, 9);
        }
        _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);
        if (t == 0) {
@@ -1167,14 +1175,18 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
 
        if (!rtlphy->rfpi_enable)
                _rtl92c_phy_pi_mode_switch(hw, true);
-       if (t == 0) {
-               rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
-               rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
-               rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
-       }
+
+       rtl_set_bbreg(hw, 0x800, BIT(24), 0x0);
+
        rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
        rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
        rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
+
+       rtl_set_bbreg(hw, 0x870, BIT(10), 0x1);
+       rtl_set_bbreg(hw, 0x870, BIT(26), 0x1);
+       rtl_set_bbreg(hw, 0x860, BIT(10), 0x0);
+       rtl_set_bbreg(hw, 0x864, BIT(10), 0x0);
+
        if (is2t) {
                rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
                rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
@@ -1239,13 +1251,9 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
                                        0x3FF0000) >> 16;
                }
        }
-       rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
-       rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
-       rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
+
        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
-       rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
-       if (is2t)
-               rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
+
        if (t != 0) {
                if (!rtlphy->rfpi_enable)
                        _rtl92c_phy_pi_mode_switch(hw, false);
@@ -1253,6 +1261,15 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
                                                  rtlphy->adda_backup, 16);
                _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,
                                                 rtlphy->iqk_mac_backup);
+               _rtl92c_phy_reload_adda_registers(hw, iqk_bb_reg_92C,
+                                                 rtlphy->iqk_bb_backup, 9);
+
+               rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
+               if (is2t)
+                       rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
+
+               rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
+               rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
        }
 }
 
index 16a0b9e59acf726745d3ad90c5480f2c4151096d..c16209a336eac66c6b7ad78afa6ac3d24b197796 100644 (file)
@@ -101,6 +101,15 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
                         "PHY_SetTxPowerLevel8192S() Channel = %d\n",
                         rtlphy->current_channel);
                rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
+               if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+                   TXHIGHPWRLEVEL_NORMAL)
+                       dm_restorepowerindex(hw);
+               else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+                        TXHIGHPWRLEVEL_LEVEL1)
+                       dm_writepowerindex(hw, 0x14);
+               else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+                        TXHIGHPWRLEVEL_LEVEL2)
+                       dm_writepowerindex(hw, 0x10);
        }
 
        rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
index d947e7d350bbc146d7b56b1c463c9dce829b5dce..fafa6bac2a3f5062b98911dc5802dd9e82fc2b95 100644 (file)
@@ -30,3 +30,6 @@
 #include "../rtl8192ce/dm.h"
 
 void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw);
+void dm_savepowerindex(struct ieee80211_hw *hw);
+void dm_writepowerindex(struct ieee80211_hw *hw, u8 value);
+void dm_restorepowerindex(struct ieee80211_hw *hw);
index 189ba124a8c6f4cfca817e77d4b0c7027c976459..468bf73cc883f41bf26222cc7aa52e17c5ed96a3 100644 (file)
@@ -1022,7 +1022,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
        if (ppsc->rfpwr_state == ERFON) {
                rtl92c_phy_set_rfpath_switch(hw, 1);
                if (iqk_initialized) {
-                       rtl92c_phy_iq_calibrate(hw, false);
+                       rtl92c_phy_iq_calibrate(hw, true);
                } else {
                        rtl92c_phy_iq_calibrate(hw, false);
                        iqk_initialized = true;
index 34e56308301e8942c9ed3f216ad307a9b6b07763..0c09240eadccdee5fe6fd6ab266c561d7019684b 100644 (file)
@@ -120,6 +120,7 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        u16 regval;
+       u32 regval32;
        u8 b_reg_hwparafile = 1;
 
        _rtl92c_phy_init_bb_rf_register_definition(hw);
@@ -135,8 +136,11 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
        } else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) {
                rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD |
                               FEN_BB_GLB_RSTn | FEN_BBRSTB);
-               rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
        }
+       regval32 = rtl_read_dword(rtlpriv, 0x87c);
+       rtl_write_dword(rtlpriv, 0x87c, regval32 & (~BIT(31)));
+       if (IS_HARDWARE_TYPE_8192CU(rtlhal))
+               rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
        rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
        if (b_reg_hwparafile == 1)
                rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
index 2119313a737bab21e9c304627b2acb56d2a3ab43..b878d56d2f4df6020449e223dfed618c4d36edbc 100644 (file)
@@ -85,17 +85,15 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
        if (mac->act_scanning) {
                tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
                tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
-               if (turbo_scanoff) {
-                       for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
-                               tx_agc[idx1] = ppowerlevel[idx1] |
-                                   (ppowerlevel[idx1] << 8) |
-                                   (ppowerlevel[idx1] << 16) |
-                                   (ppowerlevel[idx1] << 24);
-                               if (rtlhal->interface == INTF_USB) {
-                                       if (tx_agc[idx1] > 0x20 &&
-                                           rtlefuse->external_pa)
-                                               tx_agc[idx1] = 0x20;
-                               }
+               for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
+                       tx_agc[idx1] = ppowerlevel[idx1] |
+                           (ppowerlevel[idx1] << 8) |
+                           (ppowerlevel[idx1] << 16) |
+                           (ppowerlevel[idx1] << 24);
+                       if (rtlhal->interface == INTF_USB) {
+                               if (tx_agc[idx1] > 0x20 &&
+                                   rtlefuse->external_pa)
+                                       tx_agc[idx1] = 0x20;
                        }
                }
        } else {
@@ -107,7 +105,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
                           TXHIGHPWRLEVEL_LEVEL2) {
                        tx_agc[RF90_PATH_A] = 0x00000000;
                        tx_agc[RF90_PATH_B] = 0x00000000;
-               } else{
+               } else {
                        for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
                                tx_agc[idx1] = ppowerlevel[idx1] |
                                    (ppowerlevel[idx1] << 8) |
@@ -373,7 +371,12 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
                            regoffset == RTXAGC_B_MCS07_MCS04)
                                regoffset = 0xc98;
                        for (i = 0; i < 3; i++) {
-                               writeVal = (writeVal > 6) ? (writeVal - 6) : 0;
+                               if (i != 2)
+                                       writeVal = (writeVal > 8) ?
+                                                  (writeVal - 8) : 0;
+                               else
+                                       writeVal = (writeVal > 6) ?
+                                                  (writeVal - 6) : 0;
                                rtl_write_byte(rtlpriv, (u32)(regoffset + i),
                                              (u8)writeVal);
                        }
index 9936de716ad58929e50dc0e6f02fca77f5efee68..8501954cfb444d8d8f74dfb4d66cf097b45e83fd 100644 (file)
@@ -50,6 +50,9 @@ MODULE_AUTHOR("Larry Finger   <Larry.Finger@lwfinger.net>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8192cufw_A.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8192cufw_B.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8192cufw_TMSC.bin");
 
 static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
 {
@@ -69,14 +72,21 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
                         "Can't alloc buffer for fw\n");
                return 1;
        }
-
+       if (IS_VENDOR_UMC_A_CUT(rtlpriv->rtlhal.version) &&
+           !IS_92C_SERIAL(rtlpriv->rtlhal.version)) {
+               rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_A.bin";
+       } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlpriv->rtlhal.version)) {
+               rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_B.bin";
+       } else {
+               rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_TMSC.bin";
+       }
+       /* provide name of alternative file */
+       rtlpriv->cfg->alt_fw_name = "rtlwifi/rtl8192cufw.bin";
        pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name);
        rtlpriv->max_fw_size = 0x4000;
        err = request_firmware_nowait(THIS_MODULE, 1,
                                      rtlpriv->cfg->fw_name, rtlpriv->io.dev,
                                      GFP_KERNEL, hw, rtl_fw_cb);
-
-
        return err;
 }
 
index 966be519edb89b8780778ad0145e4ece80c6621a..7903c154de00d2cd193e54ed0d33a27d68ca9c1c 100644 (file)
@@ -36,7 +36,7 @@ u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH] = {
        0x804, 0x00000003,
        0x808, 0x0000fc00,
        0x80c, 0x0000000a,
-       0x810, 0x10005388,
+       0x810, 0x10000330,
        0x814, 0x020c3d10,
        0x818, 0x02200385,
        0x81c, 0x00000000,
@@ -110,22 +110,22 @@ u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH] = {
        0xc44, 0x000100b7,
        0xc48, 0xec020107,
        0xc4c, 0x007f037f,
-       0xc50, 0x6954341e,
+       0xc50, 0x69543420,
        0xc54, 0x43bc0094,
-       0xc58, 0x6954341e,
+       0xc58, 0x69543420,
        0xc5c, 0x433c0094,
        0xc60, 0x00000000,
        0xc64, 0x5116848b,
        0xc68, 0x47c00bff,
        0xc6c, 0x00000036,
        0xc70, 0x2c7f000d,
-       0xc74, 0x0186115b,
+       0xc74, 0x2186115b,
        0xc78, 0x0000001f,
        0xc7c, 0x00b99612,
        0xc80, 0x40000100,
        0xc84, 0x20f60000,
        0xc88, 0x40000100,
-       0xc8c, 0x20200000,
+       0xc8c, 0xa0e40000,
        0xc90, 0x00121820,
        0xc94, 0x00000000,
        0xc98, 0x00121820,
@@ -226,7 +226,7 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {
        0x804, 0x00000001,
        0x808, 0x0000fc00,
        0x80c, 0x0000000a,
-       0x810, 0x10005388,
+       0x810, 0x10000330,
        0x814, 0x020c3d10,
        0x818, 0x02200385,
        0x81c, 0x00000000,
@@ -300,9 +300,9 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {
        0xc44, 0x000100b7,
        0xc48, 0xec020107,
        0xc4c, 0x007f037f,
-       0xc50, 0x6954341e,
+       0xc50, 0x69543420,
        0xc54, 0x43bc0094,
-       0xc58, 0x6954341e,
+       0xc58, 0x69543420,
        0xc5c, 0x433c0094,
        0xc60, 0x00000000,
        0xc64, 0x5116848b,
@@ -340,7 +340,7 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {
        0xce4, 0x00000000,
        0xce8, 0x37644302,
        0xcec, 0x2f97d40c,
-       0xd00, 0x00080740,
+       0xd00, 0x00000740,
        0xd04, 0x00020401,
        0xd08, 0x0000907f,
        0xd0c, 0x20010201,
@@ -633,17 +633,17 @@ u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH] = {
        0x012, 0x00071000,
        0x012, 0x000b0000,
        0x012, 0x000fc000,
-       0x013, 0x000287af,
+       0x013, 0x000287b3,
        0x013, 0x000244b7,
        0x013, 0x000204ab,
        0x013, 0x0001c49f,
        0x013, 0x00018493,
-       0x013, 0x00014297,
-       0x013, 0x00010295,
-       0x013, 0x0000c298,
-       0x013, 0x0000819c,
-       0x013, 0x000040a8,
-       0x013, 0x0000001c,
+       0x013, 0x0001429b,
+       0x013, 0x00010299,
+       0x013, 0x0000c29c,
+       0x013, 0x000081a0,
+       0x013, 0x000040ac,
+       0x013, 0x00000020,
        0x014, 0x0001944c,
        0x014, 0x00059444,
        0x014, 0x0009944c,
@@ -932,10 +932,10 @@ u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH] = {
        0x608, 0x0000000e,
        0x609, 0x0000002a,
        0x652, 0x00000020,
-       0x63c, 0x0000000a,
-       0x63d, 0x0000000e,
-       0x63e, 0x0000000a,
-       0x63f, 0x0000000e,
+       0x63c, 0x00000008,
+       0x63d, 0x00000008,
+       0x63e, 0x0000000c,
+       0x63f, 0x0000000c,
        0x66e, 0x00000005,
        0x700, 0x00000021,
        0x701, 0x00000043,
index 8ed31744a0548467ad0536108b76e9fcfe0592da..4f083fc1d3607c41eb5a471f30ff04c3d234e557 100644 (file)
@@ -176,6 +176,7 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
        struct rtl_sta_info *drv_priv = NULL;
        struct ieee80211_sta *sta = NULL;
        long undec_sm_pwdb;
+       long undec_sm_cck;
 
        rcu_read_lock();
        if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
@@ -185,12 +186,16 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
        if (sta) {
                drv_priv = (struct rtl_sta_info *) sta->drv_priv;
                undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
+               undec_sm_cck = drv_priv->rssi_stat.undec_sm_cck;
        } else {
                undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
+               undec_sm_cck = rtlpriv->dm.undec_sm_cck;
        }
 
        if (undec_sm_pwdb < 0)
                undec_sm_pwdb = pstatus->rx_pwdb_all;
+       if (undec_sm_cck < 0)
+               undec_sm_cck = pstatus->rx_pwdb_all;
        if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) {
                undec_sm_pwdb = (((undec_sm_pwdb) *
                      (RX_SMOOTH_FACTOR - 1)) +
@@ -200,6 +205,15 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
                undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) +
                     (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
        }
+       if (pstatus->rx_pwdb_all > (u32) undec_sm_cck) {
+               undec_sm_cck = (((undec_sm_pwdb) *
+                     (RX_SMOOTH_FACTOR - 1)) +
+                    (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+               undec_sm_cck = undec_sm_cck + 1;
+       } else {
+               undec_sm_pwdb = (((undec_sm_cck) * (RX_SMOOTH_FACTOR - 1)) +
+                    (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+       }
 
        if (sta) {
                drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb;
index 6e2b5c5c83c8d21234ee013c802d7af317f6db8c..4933f02ce1d510cf94ef127b59ea025238ad9476 100644 (file)
@@ -475,14 +475,14 @@ static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw,
                        rtlpriv->stats.rxbytesunicast +=  skb->len;
                }
 
-               rtl_is_special_data(hw, skb, false);
-
                if (ieee80211_is_data(fc)) {
                        rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
 
                        if (unicast)
                                rtlpriv->link_info.num_rx_inperiod++;
                }
+               /* static bcn for roaming */
+               rtl_beacon_statistic(hw, skb);
        }
 }
 
@@ -517,8 +517,6 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,
                        rtlpriv->stats.rxbytesunicast +=  skb->len;
                }
 
-               rtl_is_special_data(hw, skb, false);
-
                if (ieee80211_is_data(fc)) {
                        rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
 
@@ -553,7 +551,7 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)
        }
 }
 
-#define __RX_SKB_MAX_QUEUED    32
+#define __RX_SKB_MAX_QUEUED    64
 
 static void _rtl_rx_work(unsigned long param)
 {
index 0c65386fa30d5cecda61d9d4ca290b6577df2f59..8c647391bedf0f4bc5ef4fca39b7ca39a05e1483 100644 (file)
@@ -1033,6 +1033,7 @@ struct rtl_ht_agg {
 
 struct rssi_sta {
        long undec_sm_pwdb;
+       long undec_sm_cck;
 };
 
 struct rtl_tid_data {
@@ -1323,8 +1324,10 @@ struct fast_ant_training {
 struct rtl_dm {
        /*PHY status for Dynamic Management */
        long entry_min_undec_sm_pwdb;
+       long undec_sm_cck;
        long undec_sm_pwdb;     /*out dm */
        long entry_max_undec_sm_pwdb;
+       s32 ofdm_pkt_cnt;
        bool dm_initialgain_enable;
        bool dynamic_txpower_enable;
        bool current_turbo_edca;
@@ -1339,6 +1342,7 @@ struct rtl_dm {
        bool inform_fw_driverctrldm;
        bool current_mrc_switch;
        u8 txpowercount;
+       u8 powerindex_backup[6];
 
        u8 thermalvalue_rxgain;
        u8 thermalvalue_iqk;
@@ -1350,7 +1354,9 @@ struct rtl_dm {
        bool done_txpower;
        u8 dynamic_txhighpower_lvl;     /*Tx high power level */
        u8 dm_flag;             /*Indicate each dynamic mechanism's status. */
+       u8 dm_flag_tmp;
        u8 dm_type;
+       u8 dm_rssi_sel;
        u8 txpower_track_control;
        bool interrupt_migration;
        bool disable_tx_int;
@@ -1804,6 +1810,7 @@ struct rtl_hal_cfg {
        bool write_readback;
        char *name;
        char *fw_name;
+       char *alt_fw_name;
        struct rtl_hal_ops *ops;
        struct rtl_mod_params *mod_params;
        struct rtl_hal_usbint_cfg *usb_interface_cfg;
@@ -1948,6 +1955,7 @@ struct dig_t {
        u8 pre_ccastate;
        u8 cur_ccasate;
        u8 large_fa_hit;
+       u8 dig_dynamic_min;
        u8 forbidden_igi;
        u8 dig_state;
        u8 dig_highpwrstate;
@@ -2028,22 +2036,15 @@ struct rtl_priv {
        struct dig_t dm_digtable;
        struct ps_t dm_pstable;
 
-       /* section shared by individual drivers */
-       union {
-               struct {        /* data buffer pointer for USB reads */
-                       __le32 *usb_data;
-                       int usb_data_index;
-                       bool initialized;
-               };
-               struct {        /* section for 8723ae */
-                       bool reg_init;  /* true if regs saved */
-                       u32 reg_874;
-                       u32 reg_c70;
-                       u32 reg_85c;
-                       u32 reg_a74;
-                       bool bt_operation_on;
-               };
-       };
+       u32 reg_874;
+       u32 reg_c70;
+       u32 reg_85c;
+       u32 reg_a74;
+       bool reg_init;  /* true if regs saved */
+       bool bt_operation_on;
+       __le32 *usb_data;
+       int usb_data_index;
+       bool initialized;
        bool enter_ps;  /* true when entering PS */
        u8 rate_mask[5];
 
index db6430c1a08414650a894d3e8a6d41c57cba1711..374268d5ac6a70e97355269489538ad31d802cbb 100644 (file)
@@ -18,10 +18,8 @@ int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
        wl1251_debug(DEBUG_ACX, "acx frame rates");
 
        rates = kzalloc(sizeof(*rates), GFP_KERNEL);
-       if (!rates) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!rates)
+               return -ENOMEM;
 
        rates->tx_ctrl_frame_rate = ctrl_rate;
        rates->tx_ctrl_frame_mod = ctrl_mod;
@@ -49,10 +47,8 @@ int wl1251_acx_station_id(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx dot11_station_id");
 
        mac = kzalloc(sizeof(*mac), GFP_KERNEL);
-       if (!mac) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!mac)
+               return -ENOMEM;
 
        for (i = 0; i < ETH_ALEN; i++)
                mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
@@ -74,10 +70,8 @@ int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
        wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
 
        default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
-       if (!default_key) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!default_key)
+               return -ENOMEM;
 
        default_key->id = key_id;
 
@@ -104,10 +98,8 @@ int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
        wl1251_debug(DEBUG_ACX, "acx wake up conditions");
 
        wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
-       if (!wake_up) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!wake_up)
+               return -ENOMEM;
 
        wake_up->wake_up_event = wake_up_event;
        wake_up->listen_interval = listen_interval;
@@ -132,16 +124,13 @@ int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)
        wl1251_debug(DEBUG_ACX, "acx sleep auth");
 
        auth = kzalloc(sizeof(*auth), GFP_KERNEL);
-       if (!auth) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!auth)
+               return -ENOMEM;
 
        auth->sleep_auth = sleep_auth;
 
        ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
 
-out:
        kfree(auth);
        return ret;
 }
@@ -154,10 +143,8 @@ int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
        wl1251_debug(DEBUG_ACX, "acx fw rev");
 
        rev = kzalloc(sizeof(*rev), GFP_KERNEL);
-       if (!rev) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!rev)
+               return -ENOMEM;
 
        ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
        if (ret < 0) {
@@ -191,10 +178,8 @@ int wl1251_acx_tx_power(struct wl1251 *wl, int power)
                return -EINVAL;
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx)
+               return -ENOMEM;
 
        acx->current_tx_power = power * 10;
 
@@ -217,10 +202,8 @@ int wl1251_acx_feature_cfg(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx feature cfg");
 
        feature = kzalloc(sizeof(*feature), GFP_KERNEL);
-       if (!feature) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!feature)
+               return -ENOMEM;
 
        /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
        feature->data_flow_options = 0;
@@ -261,10 +244,8 @@ int wl1251_acx_data_path_params(struct wl1251 *wl,
        wl1251_debug(DEBUG_ACX, "acx data path params");
 
        params = kzalloc(sizeof(*params), GFP_KERNEL);
-       if (!params) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!params)
+               return -ENOMEM;
 
        params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
        params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
@@ -309,10 +290,8 @@ int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time)
        wl1251_debug(DEBUG_ACX, "acx rx msdu life time");
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx)
+               return -ENOMEM;
 
        acx->lifetime = life_time;
        ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
@@ -335,10 +314,8 @@ int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter)
        wl1251_debug(DEBUG_ACX, "acx rx config");
 
        rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
-       if (!rx_config) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!rx_config)
+               return -ENOMEM;
 
        rx_config->config_options = config;
        rx_config->filter_options = filter;
@@ -363,10 +340,8 @@ int wl1251_acx_pd_threshold(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx data pd threshold");
 
        pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!pd)
+               return -ENOMEM;
 
        /* FIXME: threshold value not set */
 
@@ -389,10 +364,8 @@ int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
        wl1251_debug(DEBUG_ACX, "acx slot");
 
        slot = kzalloc(sizeof(*slot), GFP_KERNEL);
-       if (!slot) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!slot)
+               return -ENOMEM;
 
        slot->wone_index = STATION_WONE_INDEX;
        slot->slot_time = slot_time;
@@ -416,10 +389,8 @@ int wl1251_acx_group_address_tbl(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx group address tbl");
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx)
+               return -ENOMEM;
 
        /* MAC filtering */
        acx->enabled = 0;
@@ -444,10 +415,8 @@ int wl1251_acx_service_period_timeout(struct wl1251 *wl)
        int ret;
 
        rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
-       if (!rx_timeout) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!rx_timeout)
+               return -ENOMEM;
 
        wl1251_debug(DEBUG_ACX, "acx service period timeout");
 
@@ -475,10 +444,8 @@ int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold)
        wl1251_debug(DEBUG_ACX, "acx rts threshold");
 
        rts = kzalloc(sizeof(*rts), GFP_KERNEL);
-       if (!rts) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!rts)
+               return -ENOMEM;
 
        rts->threshold = rts_threshold;
 
@@ -501,10 +468,8 @@ int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter)
        wl1251_debug(DEBUG_ACX, "acx beacon filter opt");
 
        beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
-       if (!beacon_filter) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!beacon_filter)
+               return -ENOMEM;
 
        beacon_filter->enable = enable_filter;
        beacon_filter->max_num_beacons = 0;
@@ -530,10 +495,8 @@ int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx beacon filter table");
 
        ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
-       if (!ie_table) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!ie_table)
+               return -ENOMEM;
 
        /* configure default beacon pass-through rules */
        ie_table->num_ie = 1;
@@ -560,10 +523,8 @@ int wl1251_acx_conn_monit_params(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx connection monitor parameters");
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx)
+               return -ENOMEM;
 
        acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
        acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
@@ -589,10 +550,8 @@ int wl1251_acx_sg_enable(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx sg enable");
 
        pta = kzalloc(sizeof(*pta), GFP_KERNEL);
-       if (!pta) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!pta)
+               return -ENOMEM;
 
        pta->enable = SG_ENABLE;
 
@@ -615,10 +574,8 @@ int wl1251_acx_sg_cfg(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx sg cfg");
 
        param = kzalloc(sizeof(*param), GFP_KERNEL);
-       if (!param) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!param)
+               return -ENOMEM;
 
        /* BT-WLAN coext parameters */
        param->min_rate = RATE_INDEX_24MBPS;
@@ -669,10 +626,8 @@ int wl1251_acx_cca_threshold(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx cca threshold");
 
        detection = kzalloc(sizeof(*detection), GFP_KERNEL);
-       if (!detection) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!detection)
+               return -ENOMEM;
 
        detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
        detection->tx_energy_detection = 0;
@@ -682,7 +637,6 @@ int wl1251_acx_cca_threshold(struct wl1251 *wl)
        if (ret < 0)
                wl1251_warning("failed to set cca threshold: %d", ret);
 
-out:
        kfree(detection);
        return ret;
 }
@@ -695,10 +649,8 @@ int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx bcn dtim options");
 
        bb = kzalloc(sizeof(*bb), GFP_KERNEL);
-       if (!bb) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!bb)
+               return -ENOMEM;
 
        bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
        bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
@@ -724,10 +676,8 @@ int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
        wl1251_debug(DEBUG_ACX, "acx aid");
 
        acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
-       if (!acx_aid) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx_aid)
+               return -ENOMEM;
 
        acx_aid->aid = aid;
 
@@ -750,10 +700,8 @@ int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
        wl1251_debug(DEBUG_ACX, "acx event mbox mask");
 
        mask = kzalloc(sizeof(*mask), GFP_KERNEL);
-       if (!mask) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!mask)
+               return -ENOMEM;
 
        /* high event mask is unused */
        mask->high_event_mask = 0xffffffff;
@@ -805,10 +753,8 @@ int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
        wl1251_debug(DEBUG_ACX, "acx_set_preamble");
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx)
+               return -ENOMEM;
 
        acx->preamble = preamble;
 
@@ -832,10 +778,8 @@ int wl1251_acx_cts_protect(struct wl1251 *wl,
        wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx)
+               return -ENOMEM;
 
        acx->ctsprotect = ctsprotect;
 
@@ -856,10 +800,8 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
        int ret;
 
        tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
-       if (!tsf_info) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!tsf_info)
+               return -ENOMEM;
 
        ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
                                     tsf_info, sizeof(*tsf_info));
@@ -900,11 +842,8 @@ int wl1251_acx_rate_policies(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx rate policies");
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx)
+               return -ENOMEM;
 
        /* configure one default (one-size-fits-all) rate class */
        acx->rate_class_cnt = 1;
@@ -932,10 +871,8 @@ int wl1251_acx_mem_cfg(struct wl1251 *wl)
        wl1251_debug(DEBUG_ACX, "acx mem cfg");
 
        mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
-       if (!mem_conf) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!mem_conf)
+               return -ENOMEM;
 
        /* memory config */
        mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
@@ -979,10 +916,8 @@ int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
        wl1251_debug(DEBUG_ACX, "acx tbtt and dtim");
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx)
+               return -ENOMEM;
 
        acx->tbtt = tbtt;
        acx->dtim = dtim;
@@ -1008,10 +943,8 @@ int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
        wl1251_debug(DEBUG_ACX, "acx bet enable");
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx)
+               return -ENOMEM;
 
        acx->enable = mode;
        acx->max_consecutive = max_consecutive;
@@ -1037,11 +970,8 @@ int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
                     "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx)
+               return -ENOMEM;
 
        acx->ac = ac;
        acx->cw_min = cw_min;
@@ -1073,11 +1003,8 @@ int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
                     ps_scheme, ack_policy);
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!acx)
+               return -ENOMEM;
 
        acx->queue = queue;
        acx->type = type;
index 4a0bbb13806bd6fd61266c729f4a433d110ac838..7541bd1a4a4b40de9b6be249dea94ca8f95e96ae 100644 (file)
@@ -47,7 +47,7 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
                     * In active scans, we only scan channels not
                     * marked as passive.
                     */
-                   (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) {
+                   (passive || !(flags & IEEE80211_CHAN_NO_IR))) {
                        wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
                                     req->channels[i]->band,
                                     req->channels[i]->center_freq);
index 34d9dfff2ad39ead03d3da275cd3e4443385a220..9b2ecf52449faa911f25bea176ed12683fe1836e 100644 (file)
@@ -1688,7 +1688,7 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
 
                        if (channel->flags & (IEEE80211_CHAN_DISABLED |
                                              IEEE80211_CHAN_RADAR |
-                                             IEEE80211_CHAN_PASSIVE_SCAN))
+                                             IEEE80211_CHAN_NO_IR))
                                continue;
 
                        ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch);
index 0368b9cbfb896d6460da3635b199ef6266805644..e9da47cead587704c7060ebd8ab754c1aa7da16b 100644 (file)
@@ -91,8 +91,7 @@ static void wl1271_reg_notify(struct wiphy *wiphy,
                        continue;
 
                if (ch->flags & IEEE80211_CHAN_RADAR)
-                       ch->flags |= IEEE80211_CHAN_NO_IBSS |
-                                    IEEE80211_CHAN_PASSIVE_SCAN;
+                       ch->flags |= IEEE80211_CHAN_NO_IR;
 
        }
 
index 7ed86203304b700c87e4b1ca48de127f7466420f..1e3d51cd673ab6d2be132c6fda17f698547b3ff7 100644 (file)
@@ -188,16 +188,14 @@ wlcore_scan_get_channels(struct wl1271 *wl,
                flags = req_channels[i]->flags;
 
                if (force_passive)
-                       flags |= IEEE80211_CHAN_PASSIVE_SCAN;
+                       flags |= IEEE80211_CHAN_NO_IR;
 
                if ((req_channels[i]->band == band) &&
                    !(flags & IEEE80211_CHAN_DISABLED) &&
                    (!!(flags & IEEE80211_CHAN_RADAR) == radar) &&
                    /* if radar is set, we ignore the passive flag */
                    (radar ||
-                    !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) {
-
-
+                    !!(flags & IEEE80211_CHAN_NO_IR) == passive)) {
                        if (flags & IEEE80211_CHAN_RADAR) {
                                channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
 
@@ -220,7 +218,7 @@ wlcore_scan_get_channels(struct wl1271 *wl,
                            (band == IEEE80211_BAND_2GHZ) &&
                            (channels[j].channel >= 12) &&
                            (channels[j].channel <= 14) &&
-                           (flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
+                           (flags & IEEE80211_CHAN_NO_IR) &&
                            !force_passive) {
                                /* pactive channels treated as DFS */
                                channels[j].flags = SCAN_CHANNEL_FLAGS_DFS;
@@ -243,8 +241,8 @@ wlcore_scan_get_channels(struct wl1271 *wl,
                                     max_dwell_time_active,
                                     flags & IEEE80211_CHAN_RADAR ?
                                        ", DFS" : "",
-                                    flags & IEEE80211_CHAN_PASSIVE_SCAN ?
-                                       ", PASSIVE" : "");
+                                    flags & IEEE80211_CHAN_NO_IR ?
+                                       ", NO-IR" : "");
                        j++;
                }
        }
index f0358992b04fa820cb083300765271b92823320a..7a206cffb062c0b3a2521ca7a6ee22d4cd3bcefd 100644 (file)
@@ -15,8 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "common.h"
index 8c3b26a215745b755a5018764e4c0ca1f1bd52b7..776cbb80d098d37e90c0bf0e8c37736ab961f338 100644 (file)
@@ -1411,8 +1411,12 @@ struct ieee80211_vht_operation {
 #define IEEE80211_VHT_CAP_RXSTBC_MASK                          0x00000700
 #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE                        0x00000800
 #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE                        0x00001000
-#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX                   0x0000e000
-#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX              0x00070000
+#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT                  13
+#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK                  \
+               (7 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT)
+#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT            16
+#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK             \
+               (7 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT)
 #define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE                        0x00080000
 #define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE                        0x00100000
 #define IEEE80211_VHT_CAP_VHT_TXOP_PS                          0x00200000
index 3bfe8d6ee248e8e38df18e9b0462678ee76d479f..c4c5eba26d9f4cc5711de1141e313613db19b205 100644 (file)
@@ -23,9 +23,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 3eae46cb1acfecadbff979ee17e17aeab40971e7..e9abc7b536cdebb5434caae1cbd487378ad0dfe1 100644 (file)
@@ -91,9 +91,8 @@ enum ieee80211_band {
  * Channel flags set by the regulatory control code.
  *
  * @IEEE80211_CHAN_DISABLED: This channel is disabled.
- * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted
- *     on this channel.
- * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel.
+ * @IEEE80211_CHAN_NO_IR: do not initiate radiation, this includes
+ *     sending probe requests or beaconing.
  * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
  * @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel
  *     is not permitted.
@@ -113,8 +112,8 @@ enum ieee80211_band {
  */
 enum ieee80211_channel_flags {
        IEEE80211_CHAN_DISABLED         = 1<<0,
-       IEEE80211_CHAN_PASSIVE_SCAN     = 1<<1,
-       IEEE80211_CHAN_NO_IBSS          = 1<<2,
+       IEEE80211_CHAN_NO_IR            = 1<<1,
+       /* hole at 1<<2 */
        IEEE80211_CHAN_RADAR            = 1<<3,
        IEEE80211_CHAN_NO_HT40PLUS      = 1<<4,
        IEEE80211_CHAN_NO_HT40MINUS     = 1<<5,
@@ -1944,6 +1943,29 @@ struct cfg80211_update_ft_ies_params {
        size_t ie_len;
 };
 
+/**
+ * struct cfg80211_mgmt_tx_params - mgmt tx parameters
+ *
+ * This structure provides information needed to transmit a mgmt frame
+ *
+ * @chan: channel to use
+ * @offchan: indicates wether off channel operation is required
+ * @wait: duration for ROC
+ * @buf: buffer to transmit
+ * @len: buffer length
+ * @no_cck: don't use cck rates for this frame
+ * @dont_wait_for_ack: tells the low level not to wait for an ack
+ */
+struct cfg80211_mgmt_tx_params {
+       struct ieee80211_channel *chan;
+       bool offchan;
+       unsigned int wait;
+       const u8 *buf;
+       size_t len;
+       bool no_cck;
+       bool dont_wait_for_ack;
+};
+
 /**
  * struct cfg80211_ops - backend description for wireless configuration
  *
@@ -2342,9 +2364,8 @@ struct cfg80211_ops {
                                            u64 cookie);
 
        int     (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev,
-                         struct ieee80211_channel *chan, bool offchan,
-                         unsigned int wait, const u8 *buf, size_t len,
-                         bool no_cck, bool dont_wait_for_ack, u64 *cookie);
+                          struct cfg80211_mgmt_tx_params *params,
+                          u64 *cookie);
        int     (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
                                       struct wireless_dev *wdev,
                                       u64 cookie);
@@ -2438,27 +2459,6 @@ struct cfg80211_ops {
 /**
  * enum wiphy_flags - wiphy capability flags
  *
- * @WIPHY_FLAG_CUSTOM_REGULATORY:  tells us the driver for this device
- *     has its own custom regulatory domain and cannot identify the
- *     ISO / IEC 3166 alpha2 it belongs to. When this is enabled
- *     we will disregard the first regulatory hint (when the
- *     initiator is %REGDOM_SET_BY_CORE).
- * @WIPHY_FLAG_STRICT_REGULATORY: tells us the driver for this device will
- *     ignore regulatory domain settings until it gets its own regulatory
- *     domain via its regulatory_hint() unless the regulatory hint is
- *     from a country IE. After its gets its own regulatory domain it will
- *     only allow further regulatory domain settings to further enhance
- *     compliance. For example if channel 13 and 14 are disabled by this
- *     regulatory domain no user regulatory domain can enable these channels
- *     at a later time. This can be used for devices which do not have
- *     calibration information guaranteed for frequencies or settings
- *     outside of its regulatory domain. If used in combination with
- *     WIPHY_FLAG_CUSTOM_REGULATORY the inspected country IE power settings
- *     will be followed.
- * @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure
- *     that passive scan flags and beaconing flags may not be lifted by
- *     cfg80211 due to regulatory beacon hints. For more information on beacon
- *     hints read the documenation for regulatory_hint_found_beacon()
  * @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this
  *     wiphy at all
  * @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled
@@ -2497,9 +2497,9 @@ struct cfg80211_ops {
  *     beaconing mode (AP, IBSS, Mesh, ...).
  */
 enum wiphy_flags {
-       WIPHY_FLAG_CUSTOM_REGULATORY            = BIT(0),
-       WIPHY_FLAG_STRICT_REGULATORY            = BIT(1),
-       WIPHY_FLAG_DISABLE_BEACON_HINTS         = BIT(2),
+       /* use hole at 0 */
+       /* use hole at 1 */
+       /* use hole at 2 */
        WIPHY_FLAG_NETNS_OK                     = BIT(3),
        WIPHY_FLAG_PS_ON_BY_DEFAULT             = BIT(4),
        WIPHY_FLAG_4ADDR_AP                     = BIT(5),
@@ -2721,6 +2721,8 @@ struct wiphy_coalesce_support {
  * @software_iftypes: bitmask of software interface types, these are not
  *     subject to any restrictions since they are purely managed in SW.
  * @flags: wiphy flags, see &enum wiphy_flags
+ * @regulatory_flags: wiphy regulatory flags, see
+ *     &enum ieee80211_regulatory_flags
  * @features: features advertised to nl80211, see &enum nl80211_feature_flags.
  * @bss_priv_size: each BSS struct has private data allocated with it,
  *     this variable determines its size
@@ -2809,7 +2811,7 @@ struct wiphy {
 
        u16 max_acl_mac_addrs;
 
-       u32 flags, features;
+       u32 flags, regulatory_flags, features;
 
        u32 ap_sme_capa;
 
@@ -3472,6 +3474,9 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
  * custom regulatory domain will be trusted completely and as such previous
  * default channel settings will be disregarded. If no rule is found for a
  * channel on the regulatory domain the channel will be disabled.
+ * Drivers using this for a wiphy should also set the wiphy flag
+ * WIPHY_FLAG_CUSTOM_REGULATORY or cfg80211 will set it for the wiphy
+ * that called this helper.
  */
 void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
                                   const struct ieee80211_regdomain *regd);
@@ -4146,6 +4151,7 @@ void cfg80211_radar_event(struct wiphy *wiphy,
 /**
  * cfg80211_cac_event - Channel availability check (CAC) event
  * @netdev: network device
+ * @chandef: chandef for the current channel
  * @event: type of event
  * @gfp: context flags
  *
@@ -4154,6 +4160,7 @@ void cfg80211_radar_event(struct wiphy *wiphy,
  * also by full-MAC drivers.
  */
 void cfg80211_cac_event(struct net_device *netdev,
+                       const struct cfg80211_chan_def *chandef,
                        enum nl80211_radar_event event, gfp_t gfp);
 
 
@@ -4279,7 +4286,8 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
  * @dev: the device which switched channels
  * @chandef: the new channel definition
  *
- * Acquires wdev_lock, so must only be called from sleepable driver context!
+ * Caller must acquire wdev_lock, therefore must only be called from sleepable
+ * driver context!
  */
 void cfg80211_ch_switch_notify(struct net_device *dev,
                               struct cfg80211_chan_def *chandef);
index a8c2ef6d3b932abbb42e28be158d472effd02513..2179d071f68f88590c2e25ad187dc74df7931a83 100644 (file)
@@ -26,8 +26,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index d2f3041c0dfaa685b2f32a633ee0931bad036329..aec07c8a660a4fa28fd9ef59f78fa3b26a5526b5 100644 (file)
@@ -11,8 +11,7 @@
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: John Fastabend <john.r.fastabend@intel.com>
  */
index fc5d5dcebb00e88447444cf95ff525e57363a940..a975edf21b22c3678194972db693645e48dd46e6 100644 (file)
@@ -11,8 +11,7 @@
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: Lucy Liu <lucy.liu@intel.com>
  */
index 0ce93398720d1763fd4f740ded67d47b799e6bc3..63ae325305671495f565aadcf91b9ced74f0a531 100644 (file)
@@ -23,9 +23,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index 69b610acd2df9f1aefd9edd81c9cb07b8e4cca56..2a580ce9edad884fe112277e9936d5e9e8b1a482 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index bc0c6f31f1c6204d41f983c1ce3434d7f8d77258..5bbc32998d577e43990d72c56b2ac727d7e765a0 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index ae02106be59000d54c5089a313ace02a2e393bf7..5042a5021a0428c72a32c10f2120e0138e4930cd 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index e6678800c41ff27a09b59863581ba84d7c63c1cf..1f67432321c49a38394adf81e5fdc58c014b2672 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index 403081ed725ca0cffc2453cf66a19185398a5287..c5627288bca30002666df5b63cb5a73187948257 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index 0224402260a77a3653a276e0c33f2e9281601f80..8d4f588974bce7943659779b22386230a780892a 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index 0a63bbb972d7152c1daa9c9d0d058e58954cf0ad..20dcbdf258cf22c6c2e58e5bc7809be4cfdca186 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index 11417475a6c31059aa28d5db55ce90c2a536a703..664bf8178412e11c62a637ebc812d33f0861bcce 100644 (file)
@@ -24,9 +24,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index f9d88da97af2c15844caf5b9ba875cffb8a5f8c3..e4325fee1267621526959b40a53a6b66acd87ffd 100644 (file)
@@ -25,9 +25,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index 57173ae398aed4096dd8b2cc7374bd4645edc3e7..cbc12a926e5f7c554a38c9e51d06834d9b35923a 100644 (file)
@@ -24,9 +24,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index c0d938847bd3ba8fbd2e3d0b163074e25977a64b..42713c931d1fee497f000b242204c7b14416ae1d 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *     Michel Dänzer <daenzer@debian.org>, 10/2001
  *     - simplify irda_pv_t to avoid endianness issues
index cc577dc0a0efb08d689c13e9685cc30a33cece43..05a5a249956f8b18bee66e0b2bf22202a125d36b 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  * 
  *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *     
  ********************************************************************/
 
index 7ceed99a05bc79218a841352a454a980df48741b..3cd408b326de7400b00e6284be2524955beefe27 100644 (file)
@@ -154,12 +154,14 @@ struct ieee80211_low_level_stats {
  * @IEEE80211_CHANCTX_CHANGE_RADAR: radar detection flag changed
  * @IEEE80211_CHANCTX_CHANGE_CHANNEL: switched to another operating channel,
  *     this is used only with channel switching with CSA
+ * @IEEE80211_CHANCTX_CHANGE_MIN_WIDTH: The min required channel width changed
  */
 enum ieee80211_chanctx_change {
        IEEE80211_CHANCTX_CHANGE_WIDTH          = BIT(0),
        IEEE80211_CHANCTX_CHANGE_RX_CHAINS      = BIT(1),
        IEEE80211_CHANCTX_CHANGE_RADAR          = BIT(2),
        IEEE80211_CHANCTX_CHANGE_CHANNEL        = BIT(3),
+       IEEE80211_CHANCTX_CHANGE_MIN_WIDTH      = BIT(4),
 };
 
 /**
@@ -169,6 +171,7 @@ enum ieee80211_chanctx_change {
  * that contains it is visible in mac80211 only.
  *
  * @def: the channel definition
+ * @min_def: the minimum channel definition currently required.
  * @rx_chains_static: The number of RX chains that must always be
  *     active on the channel to receive MIMO transmissions
  * @rx_chains_dynamic: The number of RX chains that must be enabled
@@ -180,6 +183,7 @@ enum ieee80211_chanctx_change {
  */
 struct ieee80211_chanctx_conf {
        struct cfg80211_chan_def def;
+       struct cfg80211_chan_def min_def;
 
        u8 rx_chains_static, rx_chains_dynamic;
 
@@ -1228,6 +1232,36 @@ struct ieee80211_key_conf {
        u8 key[0];
 };
 
+/**
+ * struct ieee80211_cipher_scheme - cipher scheme
+ *
+ * This structure contains a cipher scheme information defining
+ * the secure packet crypto handling.
+ *
+ * @cipher: a cipher suite selector
+ * @iftype: a cipher iftype bit mask indicating an allowed cipher usage
+ * @hdr_len: a length of a security header used the cipher
+ * @pn_len: a length of a packet number in the security header
+ * @pn_off: an offset of pn from the beginning of the security header
+ * @key_idx_off: an offset of key index byte in the security header
+ * @key_idx_mask: a bit mask of key_idx bits
+ * @key_idx_shift: a bit shift needed to get key_idx
+ *     key_idx value calculation:
+ *      (sec_header_base[key_idx_off] & key_idx_mask) >> key_idx_shift
+ * @mic_len: a mic length in bytes
+ */
+struct ieee80211_cipher_scheme {
+       u32 cipher;
+       u16 iftype;
+       u8 hdr_len;
+       u8 pn_len;
+       u8 pn_off;
+       u8 key_idx_off;
+       u8 key_idx_mask;
+       u8 key_idx_shift;
+       u8 mic_len;
+};
+
 /**
  * enum set_key_cmd - key command
  *
@@ -1636,6 +1670,10 @@ enum ieee80211_hw_flags {
  * @uapsd_max_sp_len: maximum number of total buffered frames the WMM AP may
  *     deliver to a WMM STA during any Service Period triggered by the WMM STA.
  *     Use IEEE80211_WMM_IE_STA_QOSINFO_SP_* for correct values.
+ *
+ * @n_cipher_schemes: a size of an array of cipher schemes definitions.
+ * @cipher_schemes: a pointer to an array of cipher scheme definitions
+ *     supported by HW.
  */
 struct ieee80211_hw {
        struct ieee80211_conf conf;
@@ -1663,6 +1701,8 @@ struct ieee80211_hw {
        netdev_features_t netdev_features;
        u8 uapsd_queues;
        u8 uapsd_max_sp_len;
+       u8 n_cipher_schemes;
+       const struct ieee80211_cipher_scheme *cipher_schemes;
 };
 
 /**
index 26ba99b5a4b139cadb746c95294be3f6789f4c1b..0386b618908c8b789319ed579ba265e2a1ab5ae6 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 /*
  * Authors:
index 2c95d55f79149173d3a1f5f27bb1213dd24a323b..24948bedb64cf8cc055976e31646a204ec090683 100644 (file)
@@ -22,8 +22,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 2eca2960ca9c54116bd187b6e1e18b70060f0282..03c4650b548ca7b01c24ba0f95317139949c7cdb 100644 (file)
@@ -12,9 +12,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef __NET_HCI_H
index 400ab7ae749db0f673791108c1134135bdf8bff1..c25fbdee0d61068f69416bbec68ecc54e2d366c2 100644 (file)
@@ -13,9 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef __NFC_LLC_H_
index e5aa5acafea0e0e176e83ce50d58d33529be4669..fbfa4e471abb7f62cf31508da0f5ac3e2686fec9 100644 (file)
@@ -20,8 +20,7 @@
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 6126f1f992b40068923771cf0a7967395f88017e..0ff070e8f8de656d09f94919da587f3be1ffb938 100644 (file)
@@ -21,8 +21,7 @@
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 82fc4e43fc6e9ec156e19e18dddc4d3ec1fbe037..e80894bca1d042201c01c854df897ccc2607b72e 100644 (file)
@@ -16,9 +16,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef __NET_NFC_H
index f17ed590d64a35b314c8c9c42dc7dc153e0f1619..c96a0b86f342cc1093dee253f070f9ff225b0ba6 100644 (file)
@@ -38,17 +38,17 @@ enum environment_cap {
  *
  * @rcu_head: RCU head struct used to free the request
  * @wiphy_idx: this is set if this request's initiator is
- *     %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This
- *     can be used by the wireless core to deal with conflicts
- *     and potentially inform users of which devices specifically
- *     cased the conflicts.
+ *     %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This
+ *     can be used by the wireless core to deal with conflicts
+ *     and potentially inform users of which devices specifically
+ *     cased the conflicts.
  * @initiator: indicates who sent this request, could be any of
- *     of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*)
+ *     of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*)
  * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
- *     regulatory domain. We have a few special codes:
- *     00 - World regulatory domain
- *     99 - built by driver but a specific alpha2 cannot be determined
- *     98 - result of an intersection between two regulatory domains
+ *     regulatory domain. We have a few special codes:
+ *     00 - World regulatory domain
+ *     99 - built by driver but a specific alpha2 cannot be determined
+ *     98 - result of an intersection between two regulatory domains
  *     97 - regulatory domain has not yet been configured
  * @dfs_region: If CRDA responded with a regulatory domain that requires
  *     DFS master operation on a known DFS region (NL80211_DFS_*),
@@ -59,8 +59,8 @@ enum environment_cap {
  *     of hint passed. This could be any of the %NL80211_USER_REG_HINT_*
  *     types.
  * @intersect: indicates whether the wireless core should intersect
- *     the requested regulatory domain with the presently set regulatory
- *     domain.
+ *     the requested regulatory domain with the presently set regulatory
+ *     domain.
  * @processed: indicates whether or not this requests has already been
  *     processed. When the last request is processed it means that the
  *     currently regulatory domain set on cfg80211 is updated from
@@ -68,9 +68,9 @@ enum environment_cap {
  *     the last request is not yet processed we must yield until it
  *     is processed before processing any new requests.
  * @country_ie_checksum: checksum of the last processed and accepted
- *     country IE
+ *     country IE
  * @country_ie_env: lets us know if the AP is telling us we are outdoor,
- *     indoor, or if it doesn't matter
+ *     indoor, or if it doesn't matter
  * @list: used to insert into the reg_requests_list linked list
  */
 struct regulatory_request {
@@ -79,13 +79,63 @@ struct regulatory_request {
        enum nl80211_reg_initiator initiator;
        enum nl80211_user_reg_hint_type user_reg_hint_type;
        char alpha2[2];
-       u8 dfs_region;
+       enum nl80211_dfs_regions dfs_region;
        bool intersect;
        bool processed;
        enum environment_cap country_ie_env;
        struct list_head list;
 };
 
+/**
+ * enum ieee80211_regulatory_flags - device regulatory flags
+ *
+ * @REGULATORY_CUSTOM_REG: tells us the driver for this device
+ *     has its own custom regulatory domain and cannot identify the
+ *     ISO / IEC 3166 alpha2 it belongs to. When this is enabled
+ *     we will disregard the first regulatory hint (when the
+ *     initiator is %REGDOM_SET_BY_CORE). Drivers that use
+ *     wiphy_apply_custom_regulatory() should have this flag set
+ *     or the regulatory core will set it for the wiphy.
+ * @REGULATORY_STRICT_REG: tells us that the wiphy for this device
+ *     has regulatory domain that it wishes to be considered as the
+ *     superset for regulatory rules. After this device gets its regulatory
+ *     domain programmed further regulatory hints shall only be considered
+ *     for this device to enhance regulatory compliance, forcing the
+ *     device to only possibly use subsets of the original regulatory
+ *     rules. For example if channel 13 and 14 are disabled by this
+ *     device's regulatory domain no user specified regulatory hint which
+ *     has these channels enabled would enable them for this wiphy,
+ *     the device's original regulatory domain will be trusted as the
+ *     base. You can program the superset of regulatory rules for this
+ *     wiphy with regulatory_hint() for cards programmed with an
+ *     ISO3166-alpha2 country code. wiphys that use regulatory_hint()
+ *     will have their wiphy->regd programmed once the regulatory
+ *     domain is set, and all other regulatory hints will be ignored
+ *     until their own regulatory domain gets programmed.
+ * @REGULATORY_DISABLE_BEACON_HINTS: enable this if your driver needs to
+ *     ensure that passive scan flags and beaconing flags may not be lifted by
+ *     cfg80211 due to regulatory beacon hints. For more information on beacon
+ *     hints read the documenation for regulatory_hint_found_beacon()
+ * @REGULATORY_COUNTRY_IE_FOLLOW_POWER:  for devices that have a preference
+ *     that even though they may have programmed their own custom power
+ *     setting prior to wiphy registration, they want to ensure their channel
+ *     power settings are updated for this connection with the power settings
+ *     derived from the regulatory domain. The regulatory domain used will be
+ *     based on the ISO3166-alpha2 from country IE provided through
+ *     regulatory_hint_country_ie()
+ * @REGULATORY_COUNTRY_IE_IGNORE: for devices that have a preference to ignore
+ *     all country IE information processed by the regulatory core. This will
+ *     override %REGULATORY_COUNTRY_IE_FOLLOW_POWER as all country IEs will
+ *     be ignored.
+ */
+enum ieee80211_regulatory_flags {
+       REGULATORY_CUSTOM_REG                   = BIT(0),
+       REGULATORY_STRICT_REG                   = BIT(1),
+       REGULATORY_DISABLE_BEACON_HINTS         = BIT(2),
+       REGULATORY_COUNTRY_IE_FOLLOW_POWER      = BIT(3),
+       REGULATORY_COUNTRY_IE_IGNORE            = BIT(4),
+};
+
 struct ieee80211_freq_range {
        u32 start_freq_khz;
        u32 end_freq_khz;
@@ -107,7 +157,7 @@ struct ieee80211_regdomain {
        struct rcu_head rcu_head;
        u32 n_reg_rules;
        char alpha2[2];
-       u8 dfs_region;
+       enum nl80211_dfs_regions dfs_region;
        struct ieee80211_reg_rule reg_rules[];
 };
 
index aa80bef3c9d5392b8cf472013c4f1da8f7de87f4..f2d58aa37a6fef8438d0ea0ea1ebce870a2a31bb 100644 (file)
@@ -16,9 +16,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 6bd44fe94c26382e1130b9b989d1ed6efb68b349..4a5b9a306c69b4139c8811138204410bb791e79b 100644 (file)
@@ -19,9 +19,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 832f2191489c946bebd68ce8b6cdfa92c0086979..4b7cd695e43187c39eeae537bdc031d44ba63abc 100644 (file)
@@ -19,9 +19,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 2f0a565a0fd57ee6914b60512d531fb057729d83..307728f622efa6b2b3cbb58b99d77f62c9941437 100644 (file)
@@ -19,9 +19,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index c5fe80697f8d442d9c52cb4aabc9b4edfff85223..610a8c8738fa63d48b7200272b289585e61a1405 100644 (file)
@@ -21,9 +21,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 4ef75af340b633c7e8a5fabeb34dd88cdbd73ef2..7f4eeb340a54af17cd1e4a97631f3b86ede9214d 100644 (file)
@@ -21,9 +21,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email addresses:
index ea0ca5f6e629cc8eb2e05e53b1531379617b3b79..e416d6ac9c700b0f6ae3cf6629aec1e092a579c9 100644 (file)
@@ -19,9 +19,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email addresses:
index 54bbbe547303cc8d37c88d736e9e95894e054a69..31b8dbaad45a62f438f89069f0d22ec4fef19deb 100644 (file)
@@ -22,9 +22,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 27b9f5c90153610e75d9a7023b808e5b61174c33..daacb32b55b576359443cb57d184a8c6639d4956 100644 (file)
@@ -25,9 +25,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index b0cf5d54d717a553a9135044237c2db563253b23..e0dce07b87947ca11a1af9b2c8fec10036746633 100644 (file)
@@ -24,9 +24,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email addresses:
index e103fe02f37571aa0436878897f1fd98a872aa09..dd5d86fab030c8fb8d16d6acad7eefebcab375b9 100644 (file)
@@ -11,8 +11,7 @@
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: Alexander Duyck <alexander.h.duyck@intel.com>
  */
index 70e55d200610ec6596f7c90715bff4749b462f6e..f7e1ab2139efe7f6208836c1797a2db6fb603749 100644 (file)
@@ -282,6 +282,7 @@ extern int sysctl_tcp_limit_output_bytes;
 extern int sysctl_tcp_challenge_ack_limit;
 extern unsigned int sysctl_tcp_notsent_lowat;
 extern int sysctl_tcp_min_tso_segs;
+extern int sysctl_tcp_autocorking;
 
 extern atomic_long_t tcp_memory_allocated;
 extern struct percpu_counter tcp_sockets_allocated;
index 18afa495f9737b9915732b953729ee7f2dd91459..5d66caeba3eec38b725e2a7b37edaa3450713e3a 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef _XT_OSF_H
index f752e9821e717ee68066f4d8467775a8bee2fd78..129b7b08714848279f3638019892a4dc0e9e6d65 100644 (file)
  *     operation, %NL80211_ATTR_MAC contains the peer MAC address, and
  *     %NL80211_ATTR_REASON_CODE the reason code to be used (only with
  *     %NL80211_TDLS_TEARDOWN).
- * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame.
+ * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. The
+ *     %NL80211_ATTR_TDLS_ACTION attribute determines the type of frame to be
+ *     sent. Public Action codes (802.11-2012 8.1.5.1) will be sent as
+ *     802.11 management frames, while TDLS action codes (802.11-2012
+ *     8.5.13.1) will be encapsulated and sent as data frames. The currently
+ *     supported Public Action code is %WLAN_PUB_ACTION_TDLS_DISCOVER_RES
+ *     and the currently supported TDLS actions codes are given in
+ *     &enum ieee80211_tdls_actioncode.
  *
  * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
  *     (or GO) interface (i.e. hostapd) to ask for unexpected frames to
@@ -1508,6 +1515,11 @@ enum nl80211_commands {
  *     to react to radar events, e.g. initiate a channel switch or leave the
  *     IBSS network.
  *
+ * @NL80211_ATTR_SUPPORT_5_MHZ: A flag indicating that the device supports
+ *     5 MHz channel bandwidth.
+ * @NL80211_ATTR_SUPPORT_10_MHZ: A flag indicating that the device supports
+ *     10 MHz channel bandwidth.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1824,6 +1836,9 @@ enum nl80211_attrs {
 
        NL80211_ATTR_HANDLE_DFS,
 
+       NL80211_ATTR_SUPPORT_5_MHZ,
+       NL80211_ATTR_SUPPORT_10_MHZ,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -2224,10 +2239,9 @@ enum nl80211_band_attr {
  * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz
  * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current
  *     regulatory domain.
- * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is
- *     permitted on this channel in current regulatory domain.
- * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted
- *     on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation
+ *     are permitted on this channel, this includes sending probe
+ *     requests, or modes of operation that require beaconing.
  * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory
  *     on this channel in current regulatory domain.
  * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm
@@ -2254,8 +2268,8 @@ enum nl80211_frequency_attr {
        __NL80211_FREQUENCY_ATTR_INVALID,
        NL80211_FREQUENCY_ATTR_FREQ,
        NL80211_FREQUENCY_ATTR_DISABLED,
-       NL80211_FREQUENCY_ATTR_PASSIVE_SCAN,
-       NL80211_FREQUENCY_ATTR_NO_IBSS,
+       NL80211_FREQUENCY_ATTR_NO_IR,
+       __NL80211_FREQUENCY_ATTR_NO_IBSS,
        NL80211_FREQUENCY_ATTR_RADAR,
        NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
        NL80211_FREQUENCY_ATTR_DFS_STATE,
@@ -2271,6 +2285,9 @@ enum nl80211_frequency_attr {
 };
 
 #define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER
+#define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN    NL80211_FREQUENCY_ATTR_NO_IR
+#define NL80211_FREQUENCY_ATTR_NO_IBSS         NL80211_FREQUENCY_ATTR_NO_IR
+#define NL80211_FREQUENCY_ATTR_NO_IR           NL80211_FREQUENCY_ATTR_NO_IR
 
 /**
  * enum nl80211_bitrate_attr - bitrate attributes
@@ -2413,8 +2430,9 @@ enum nl80211_sched_scan_match_attr {
  * @NL80211_RRF_DFS: DFS support is required to be used
  * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links
  * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links
- * @NL80211_RRF_PASSIVE_SCAN: passive scan is required
- * @NL80211_RRF_NO_IBSS: no IBSS is allowed
+ * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed,
+ *     this includes probe requests or modes of operation that require
+ *     beaconing.
  */
 enum nl80211_reg_rule_flags {
        NL80211_RRF_NO_OFDM             = 1<<0,
@@ -2424,10 +2442,17 @@ enum nl80211_reg_rule_flags {
        NL80211_RRF_DFS                 = 1<<4,
        NL80211_RRF_PTP_ONLY            = 1<<5,
        NL80211_RRF_PTMP_ONLY           = 1<<6,
-       NL80211_RRF_PASSIVE_SCAN        = 1<<7,
-       NL80211_RRF_NO_IBSS             = 1<<8,
+       NL80211_RRF_NO_IR               = 1<<7,
+       __NL80211_RRF_NO_IBSS           = 1<<8,
 };
 
+#define NL80211_RRF_PASSIVE_SCAN       NL80211_RRF_NO_IR
+#define NL80211_RRF_NO_IBSS            NL80211_RRF_NO_IR
+#define NL80211_RRF_NO_IR              NL80211_RRF_NO_IR
+
+/* For backport compatibility with older userspace */
+#define NL80211_RRF_NO_IR_ALL          (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS)
+
 /**
  * enum nl80211_dfs_regions - regulatory DFS regions
  *
index ca451e99b28b92f5a5e1d8fde7d99446e2df06cf..266022a2be4acae990ed56c3efe783766d667d6e 100644 (file)
@@ -22,9 +22,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 1bdb4a39d1e1512da2091f1c4e897c5e03527554..bbaba22f2d1bcfa25517acb1bf19fc8eb648c480 100644 (file)
@@ -258,6 +258,7 @@ enum
        LINUX_MIB_TCPFASTOPENCOOKIEREQD,        /* TCPFastOpenCookieReqd */
        LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES, /* TCPSpuriousRtxHostQueues */
        LINUX_MIB_BUSYPOLLRXPACKETS,            /* BusyPollRxPackets */
+       LINUX_MIB_TCPAUTOCORKING,               /* TCPAutoCorking */
        __LINUX_MIB_MAX
 };
 
index e7ee5314f39a1e6a611dd3f0bd59c10c012ae699..5a5b16f365e9baae89f345b22930f1109e5f0b4c 100644 (file)
@@ -12,8 +12,7 @@
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
 #ifndef _BNEP_H
index eae67bf0446c8023b6e3895562e48912b6c29330..8d3f8c7651f0dcec64bc7cac84a7f9c3d8953352 100644 (file)
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/if_ether.h>
index ba3b7ea5ebb3139cca38e82ac6f5f5e346f4a4e0..c98052487e986df6657e32da066630e95d3557bb 100644 (file)
@@ -3981,8 +3981,7 @@ struct sk_buff *napi_get_frags(struct napi_struct *napi)
 
        if (!skb) {
                skb = netdev_alloc_skb_ip_align(napi->dev, GRO_MAX_HEAD);
-               if (skb)
-                       napi->skb = skb;
+               napi->skb = skb;
        }
        return skb;
 }
index 4f72fc40bf029b6e18f2828c57d666ab6ba0bf44..a520d8004d895d421ee1f99bb78e4cf83bd858c5 100644 (file)
@@ -11,8 +11,7 @@
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: John Fastabend <john.r.fastabend@intel.com>
  */
index 40d5829ed36aaa6945c9c4c2056325b68ab64c03..66fbe1948fb5d290a867a8517ffd0e70e85038e4 100644 (file)
@@ -11,8 +11,7 @@
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: Lucy Liu <lucy.liu@intel.com>
  */
index f347a2ca7d7e6c5c1f6feae5e8edae91b487500e..bf85843390488d7768e3b3457c7e9e1139e50c19 100644 (file)
@@ -19,8 +19,7 @@
  *   the GNU Lesser General Public License for more details.
  *
  *   You should have received a copy of the GNU Lesser General Public License
- *   along with this library; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *   along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/module.h>
 #include <linux/moduleparam.h>
index c32be292c7e382c4a2c600e9e3c559906ff9784b..e7b6d53eef88d250d6a93e3a75f26c3a6cad4cba 100644 (file)
@@ -32,8 +32,7 @@
  *   the GNU Lesser General Public License for more details.
  *
  *   You should have received a copy of the GNU Lesser General Public License
- *   along with this library; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *   along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/module.h>
index 17c7886b5b3a2a35807a6f4aad4ce52a0f0f3468..7af1ed39c0091de232f5b487ac557ba76e3e9b59 100644 (file)
@@ -15,8 +15,7 @@
  *   the GNU Lesser General Public License for more details.
  *
  *   You should have received a copy of the GNU Lesser General Public License
- *   along with this library; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *   along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/compiler.h>
index 667c1d4ca9847c627127dc633e19c7c94f354188..4b59b6e488d3e61ec919a263a0e1c347d9335e43 100644 (file)
@@ -31,8 +31,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 5f011cc89cd979742844febe4cc6117a9332d5c9..61a942265e8abd963e169cb990d7a3e008b06e04 100644 (file)
@@ -34,8 +34,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: James Morris <jmorris@intercode.com.au>
  *
index 4a0335854b89c305442e257057ca560811159df8..8ecd7ad959b4c9a1e29d6cf68501c7ba26f0bdf1 100644 (file)
@@ -279,6 +279,7 @@ static const struct snmp_mib snmp4_net_list[] = {
        SNMP_MIB_ITEM("TCPFastOpenCookieReqd", LINUX_MIB_TCPFASTOPENCOOKIEREQD),
        SNMP_MIB_ITEM("TCPSpuriousRtxHostQueues", LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES),
        SNMP_MIB_ITEM("BusyPollRxPackets", LINUX_MIB_BUSYPOLLRXPACKETS),
+       SNMP_MIB_ITEM("TCPAutoCorking", LINUX_MIB_TCPAUTOCORKING),
        SNMP_MIB_SENTINEL
 };
 
index 3d69ec8dac578ee101e2c4b9467b3be83a430ac6..38c8ec90ff680001656f9ab53ee838b85827f9ea 100644 (file)
@@ -732,6 +732,15 @@ static struct ctl_table ipv4_table[] = {
                .extra1         = &zero,
                .extra2         = &gso_max_segs,
        },
+       {
+               .procname       = "tcp_autocorking",
+               .data           = &sysctl_tcp_autocorking,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &one,
+       },
        {
                .procname       = "udp_mem",
                .data           = &sysctl_udp_mem,
index c4638e6f023843bedbceb91f1bef3c424ad3b666..0ca87547becbe939c19e93c6f68983c40087da86 100644 (file)
@@ -285,6 +285,8 @@ int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
 
 int sysctl_tcp_min_tso_segs __read_mostly = 2;
 
+int sysctl_tcp_autocorking __read_mostly = 1;
+
 struct percpu_counter tcp_orphan_count;
 EXPORT_SYMBOL_GPL(tcp_orphan_count);
 
@@ -619,19 +621,52 @@ static inline void tcp_mark_urg(struct tcp_sock *tp, int flags)
                tp->snd_up = tp->write_seq;
 }
 
-static inline void tcp_push(struct sock *sk, int flags, int mss_now,
-                           int nonagle)
+/* If a not yet filled skb is pushed, do not send it if
+ * we have packets in Qdisc or NIC queues :
+ * Because TX completion will happen shortly, it gives a chance
+ * to coalesce future sendmsg() payload into this skb, without
+ * need for a timer, and with no latency trade off.
+ * As packets containing data payload have a bigger truesize
+ * than pure acks (dataless) packets, the last check prevents
+ * autocorking if we only have an ACK in Qdisc/NIC queues.
+ */
+static bool tcp_should_autocork(struct sock *sk, struct sk_buff *skb,
+                               int size_goal)
 {
-       if (tcp_send_head(sk)) {
-               struct tcp_sock *tp = tcp_sk(sk);
+       return skb->len < size_goal &&
+              sysctl_tcp_autocorking &&
+              atomic_read(&sk->sk_wmem_alloc) > skb->truesize;
+}
+
+static void tcp_push(struct sock *sk, int flags, int mss_now,
+                    int nonagle, int size_goal)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct sk_buff *skb;
 
-               if (!(flags & MSG_MORE) || forced_push(tp))
-                       tcp_mark_push(tp, tcp_write_queue_tail(sk));
+       if (!tcp_send_head(sk))
+               return;
+
+       skb = tcp_write_queue_tail(sk);
+       if (!(flags & MSG_MORE) || forced_push(tp))
+               tcp_mark_push(tp, skb);
+
+       tcp_mark_urg(tp, flags);
+
+       if (tcp_should_autocork(sk, skb, size_goal)) {
 
-               tcp_mark_urg(tp, flags);
-               __tcp_push_pending_frames(sk, mss_now,
-                                         (flags & MSG_MORE) ? TCP_NAGLE_CORK : nonagle);
+               /* avoid atomic op if TSQ_THROTTLED bit is already set */
+               if (!test_bit(TSQ_THROTTLED, &tp->tsq_flags)) {
+                       NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAUTOCORKING);
+                       set_bit(TSQ_THROTTLED, &tp->tsq_flags);
+               }
+               return;
        }
+
+       if (flags & MSG_MORE)
+               nonagle = TCP_NAGLE_CORK;
+
+       __tcp_push_pending_frames(sk, mss_now, nonagle);
 }
 
 static int tcp_splice_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
@@ -934,7 +969,8 @@ new_segment:
 wait_for_sndbuf:
                set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 wait_for_memory:
-               tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
+               tcp_push(sk, flags & ~MSG_MORE, mss_now,
+                        TCP_NAGLE_PUSH, size_goal);
 
                if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
                        goto do_error;
@@ -944,7 +980,7 @@ wait_for_memory:
 
 out:
        if (copied && !(flags & MSG_SENDPAGE_NOTLAST))
-               tcp_push(sk, flags, mss_now, tp->nonagle);
+               tcp_push(sk, flags, mss_now, tp->nonagle, size_goal);
        return copied;
 
 do_error:
@@ -1225,7 +1261,8 @@ wait_for_sndbuf:
                        set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 wait_for_memory:
                        if (copied)
-                               tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
+                               tcp_push(sk, flags & ~MSG_MORE, mss_now,
+                                        TCP_NAGLE_PUSH, size_goal);
 
                        if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
                                goto do_error;
@@ -1236,7 +1273,7 @@ wait_for_memory:
 
 out:
        if (copied)
-               tcp_push(sk, flags, mss_now, tp->nonagle);
+               tcp_push(sk, flags, mss_now, tp->nonagle, size_goal);
        release_sock(sk);
        return copied + copied_syn;
 
index 7820f3a7dd704bd6375c5cdc858e71b7be4261ed..993da005e0878d1489deee34d611ed520c3a6012 100644 (file)
@@ -363,15 +363,17 @@ static inline void TCP_ECN_send(struct sock *sk, struct sk_buff *skb,
  */
 static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags)
 {
+       struct skb_shared_info *shinfo = skb_shinfo(skb);
+
        skb->ip_summed = CHECKSUM_PARTIAL;
        skb->csum = 0;
 
        TCP_SKB_CB(skb)->tcp_flags = flags;
        TCP_SKB_CB(skb)->sacked = 0;
 
-       skb_shinfo(skb)->gso_segs = 1;
-       skb_shinfo(skb)->gso_size = 0;
-       skb_shinfo(skb)->gso_type = 0;
+       shinfo->gso_segs = 1;
+       shinfo->gso_size = 0;
+       shinfo->gso_type = 0;
 
        TCP_SKB_CB(skb)->seq = seq;
        if (flags & (TCPHDR_SYN | TCPHDR_FIN))
@@ -986,6 +988,8 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
 static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb,
                                 unsigned int mss_now)
 {
+       struct skb_shared_info *shinfo = skb_shinfo(skb);
+
        /* Make sure we own this skb before messing gso_size/gso_segs */
        WARN_ON_ONCE(skb_cloned(skb));
 
@@ -993,13 +997,13 @@ static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb,
                /* Avoid the costly divide in the normal
                 * non-TSO case.
                 */
-               skb_shinfo(skb)->gso_segs = 1;
-               skb_shinfo(skb)->gso_size = 0;
-               skb_shinfo(skb)->gso_type = 0;
+               shinfo->gso_segs = 1;
+               shinfo->gso_size = 0;
+               shinfo->gso_type = 0;
        } else {
-               skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss_now);
-               skb_shinfo(skb)->gso_size = mss_now;
-               skb_shinfo(skb)->gso_type = sk->sk_gso_type;
+               shinfo->gso_segs = DIV_ROUND_UP(skb->len, mss_now);
+               shinfo->gso_size = mss_now;
+               shinfo->gso_type = sk->sk_gso_type;
        }
 }
 
@@ -1146,6 +1150,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
  */
 static void __pskb_trim_head(struct sk_buff *skb, int len)
 {
+       struct skb_shared_info *shinfo;
        int i, k, eat;
 
        eat = min_t(int, len, skb_headlen(skb));
@@ -1157,23 +1162,24 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
        }
        eat = len;
        k = 0;
-       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-               int size = skb_frag_size(&skb_shinfo(skb)->frags[i]);
+       shinfo = skb_shinfo(skb);
+       for (i = 0; i < shinfo->nr_frags; i++) {
+               int size = skb_frag_size(&shinfo->frags[i]);
 
                if (size <= eat) {
                        skb_frag_unref(skb, i);
                        eat -= size;
                } else {
-                       skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i];
+                       shinfo->frags[k] = shinfo->frags[i];
                        if (eat) {
-                               skb_shinfo(skb)->frags[k].page_offset += eat;
-                               skb_frag_size_sub(&skb_shinfo(skb)->frags[k], eat);
+                               shinfo->frags[k].page_offset += eat;
+                               skb_frag_size_sub(&shinfo->frags[k], eat);
                                eat = 0;
                        }
                        k++;
                }
        }
-       skb_shinfo(skb)->nr_frags = k;
+       shinfo->nr_frags = k;
 
        skb_reset_tail_pointer(skb);
        skb->data_len -= len;
index 82e1da3a40b915e65c2ecf15662415511cc91286..81e496a2e0083c42fe94729a486647aa23c8aed0 100644 (file)
@@ -12,8 +12,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors
  *
index b8719df0366eb30759b39c72fd8ba28a0c0f67ed..6eef8a7e35f2c54514e6bbb8871d18ff18ae691e 100644 (file)
@@ -12,8 +12,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors
  *
index 4acdb63495dbe2484de9d278b810401e6d26fc6a..9a311cc79672440cfaff2812f5e300817e789fa9 100644 (file)
@@ -336,7 +336,8 @@ int ip6_forward(struct sk_buff *skb)
                goto drop;
 
        if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
-               IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
+               IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
+                                IPSTATS_MIB_INDISCARDS);
                goto drop;
        }
 
@@ -370,8 +371,8 @@ int ip6_forward(struct sk_buff *skb)
                /* Force OUTPUT device used as source address */
                skb->dev = dst->dev;
                icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0);
-               IP6_INC_STATS_BH(net,
-                                ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
+               IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
+                                IPSTATS_MIB_INHDRERRORS);
 
                kfree_skb(skb);
                return -ETIMEDOUT;
@@ -384,14 +385,15 @@ int ip6_forward(struct sk_buff *skb)
                if (proxied > 0)
                        return ip6_input(skb);
                else if (proxied < 0) {
-                       IP6_INC_STATS(net, ip6_dst_idev(dst),
-                                     IPSTATS_MIB_INDISCARDS);
+                       IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
+                                        IPSTATS_MIB_INDISCARDS);
                        goto drop;
                }
        }
 
        if (!xfrm6_route_forward(skb)) {
-               IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
+               IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
+                                IPSTATS_MIB_INDISCARDS);
                goto drop;
        }
        dst = skb_dst(skb);
@@ -448,16 +450,17 @@ int ip6_forward(struct sk_buff *skb)
                /* Again, force OUTPUT device used as source address */
                skb->dev = dst->dev;
                icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
-               IP6_INC_STATS_BH(net,
-                                ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS);
-               IP6_INC_STATS_BH(net,
-                                ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS);
+               IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
+                                IPSTATS_MIB_INTOOBIGERRORS);
+               IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
+                                IPSTATS_MIB_FRAGFAILS);
                kfree_skb(skb);
                return -EMSGSIZE;
        }
 
        if (skb_cow(skb, dst->dev->hard_header_len)) {
-               IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS);
+               IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
+                                IPSTATS_MIB_OUTDISCARDS);
                goto drop;
        }
 
index ce507d9e1c900d3990e6025b37087309f850eaca..da9becb42e8127283f59c70731dc2890701f769e 100644 (file)
@@ -16,8 +16,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 /*
  * [Memo]
index 9ac01dc9402e9337d4b27952127d229acbb6e062..db9b6cbc9db3905695888343912be7dfd06af6f2 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 /*
  * Authors:
index 4b0f50d9a962d9cab94e2a567d23183fe6dac441..2c4e4c5c7614bf9ee864a99e095c7c17e46d9b57 100644 (file)
@@ -12,8 +12,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors     Mitsuru KANDA  <mk@linux-ipv6.org>
  *             YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
index 63d5d493098afd6b250e77b3ef15a880bd7232c7..0e015906f9ca91e11d3e9e124c532c6a7cb04c5d 100644 (file)
@@ -15,8 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 /*
  * Authors:
index de2bcfaaf759c95df42effbdd24a0593247ecb1a..1c66465a42ddc09627dae47d4c6cbd40aa4fdc35 100644 (file)
@@ -12,8 +12,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors     Mitsuru KANDA  <mk@linux-ipv6.org>
  *             YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
index de7db23049f141be0b6f319db136e7d1a3c5a1f1..73baf9b346b65840bf4ceecf3e8d340e30d32526 100644 (file)
@@ -25,9 +25,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *     Linux-IrDA now supports four different types of IrDA sockets:
  *
index b0b56a339a835686c16f29fd7409aa2959718459..6786e7f193d298ba0a0b46ed28d4144ad9084743 100644 (file)
@@ -24,9 +24,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index b797daac063c2231efb0dc053bbf51301dae756d..4490a675b1bbe653117afe4fad0ee24d9dcb30f5 100644 (file)
@@ -23,9 +23,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index d78554fedbac5e98c32ac664bd595f1d35373fa5..b172c65223282888e90c1a45cf24383e63c33d8a 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 3b8095c771d44371cfdb97b5607fb28817791fb8..6536114adf37a285db123efc0aa7c945d460f318 100644 (file)
@@ -24,9 +24,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 30893912835926a2bbc83ce716a1fdbf242c81a4..f80b1a6a244bcadc63124d4a303adc8163b94667 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 6e6509f22f60913296e9b8971e6304155a5f3b1c..d362d711b79c8cb36283667387e142538b1e515a 100644 (file)
@@ -23,9 +23,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 41ac7938268be6ca07401bf0e9596c9e604444be..2ba8b9705bb75201715844105206ecfc3b480df7 100644 (file)
@@ -24,9 +24,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index a2a508f5f2684e81ea69697e3e84ff69f2fe74da..2ee87bf387cc191147ce9bb3809b6fd1e3096cc4 100644 (file)
@@ -23,9 +23,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index b343f50dc8d72a07b321d9e70eb33e3ed8f62443..ce943853c38d6a913e6d5a113f1a71857537fb69 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 14653b8d664dba5d83129b98230ddfe010674111..365b895da84b5ef3565527675e4103ba05b6dffe 100644 (file)
@@ -23,9 +23,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 005b424494a0bd4009fac7910cbb81f37bf5837c..a778df55f5d67123c332ce6400212cd59093bfd4 100644 (file)
@@ -23,9 +23,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 71cd38c1a67fcfe241215effff78efba06be966c..6d0869716bf680f91670bfa8e48f999137bb09fe 100644 (file)
@@ -22,9 +22,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 798ffd9a705ee014671248e71a213b557031ecac..11a7cc0cbc2877c7baf2105ad9dfc7880991ad98 100644 (file)
@@ -24,9 +24,7 @@
  *     GNU General Public License for more details.
  *
  *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *     MA 02111-1307 USA
+ *     along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  ********************************************************************/
 
index 364ce0c5962fd48c85ea23b71b2d1dd463082575..f80e8c4c6bcd303762781ed8a2aa613ff763f5fa 100644 (file)
@@ -133,7 +133,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
                             struct key_params *params)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_local *local = sdata->local;
        struct sta_info *sta = NULL;
+       const struct ieee80211_cipher_scheme *cs = NULL;
        struct ieee80211_key *key;
        int err;
 
@@ -145,22 +147,28 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
        case WLAN_CIPHER_SUITE_WEP40:
        case WLAN_CIPHER_SUITE_TKIP:
        case WLAN_CIPHER_SUITE_WEP104:
-               if (IS_ERR(sdata->local->wep_tx_tfm))
+               if (IS_ERR(local->wep_tx_tfm))
                        return -EINVAL;
                break;
+       case WLAN_CIPHER_SUITE_CCMP:
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+       case WLAN_CIPHER_SUITE_GCMP:
+               break;
        default:
+               cs = ieee80211_cs_get(local, params->cipher, sdata->vif.type);
                break;
        }
 
        key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len,
-                                 params->key, params->seq_len, params->seq);
+                                 params->key, params->seq_len, params->seq,
+                                 cs);
        if (IS_ERR(key))
                return PTR_ERR(key);
 
        if (pairwise)
                key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
 
-       mutex_lock(&sdata->local->sta_mtx);
+       mutex_lock(&local->sta_mtx);
 
        if (mac_addr) {
                if (ieee80211_vif_is_mesh(&sdata->vif))
@@ -216,10 +224,13 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
                break;
        }
 
+       if (sta)
+               sta->cipher_scheme = cs;
+
        err = ieee80211_key_link(key, sdata, sta);
 
  out_unlock:
-       mutex_unlock(&sdata->local->sta_mtx);
+       mutex_unlock(&local->sta_mtx);
 
        return err;
 }
@@ -244,7 +255,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
                        goto out_unlock;
 
                if (pairwise)
-                       key = key_mtx_dereference(local, sta->ptk);
+                       key = key_mtx_dereference(local, sta->ptk[key_idx]);
                else
                        key = key_mtx_dereference(local, sta->gtk[key_idx]);
        } else
@@ -291,7 +302,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
                        goto out;
 
                if (pairwise)
-                       key = rcu_dereference(sta->ptk);
+                       key = rcu_dereference(sta->ptk[key_idx]);
                else if (key_idx < NUM_DEFAULT_KEYS)
                        key = rcu_dereference(sta->gtk[key_idx]);
        } else
@@ -521,8 +532,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
                                 STATION_INFO_PEER_PM |
                                 STATION_INFO_NONPEER_PM;
 
-               sinfo->llid = le16_to_cpu(sta->llid);
-               sinfo->plid = le16_to_cpu(sta->plid);
+               sinfo->llid = sta->llid;
+               sinfo->plid = sta->plid;
                sinfo->plink_state = sta->plink_state;
                if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
                        sinfo->filled |= STATION_INFO_T_OFFSET;
@@ -846,7 +857,7 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
        if (!resp || !resp_len)
                return 1;
 
-       old = rtnl_dereference(sdata->u.ap.probe_resp);
+       old = sdata_dereference(sdata->u.ap.probe_resp, sdata);
 
        new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL);
        if (!new)
@@ -870,7 +881,8 @@ int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
        int size, err;
        u32 changed = BSS_CHANGED_BEACON;
 
-       old = rtnl_dereference(sdata->u.ap.beacon);
+       old = sdata_dereference(sdata->u.ap.beacon, sdata);
+
 
        /* Need to have a beacon head if we don't have one yet */
        if (!params->head && !old)
@@ -947,7 +959,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
                      BSS_CHANGED_P2P_PS;
        int err;
 
-       old = rtnl_dereference(sdata->u.ap.beacon);
+       old = sdata_dereference(sdata->u.ap.beacon, sdata);
        if (old)
                return -EALREADY;
 
@@ -968,11 +980,19 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
         */
        sdata->control_port_protocol = params->crypto.control_port_ethertype;
        sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt;
+       sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local,
+                                                       &params->crypto,
+                                                       sdata->vif.type);
+
        list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
                vlan->control_port_protocol =
                        params->crypto.control_port_ethertype;
                vlan->control_port_no_encrypt =
                        params->crypto.control_port_no_encrypt;
+               vlan->encrypt_headroom =
+                       ieee80211_cs_headroom(sdata->local,
+                                             &params->crypto,
+                                             vlan->vif.type);
        }
 
        sdata->vif.bss_conf.beacon_int = params->beacon_interval;
@@ -1001,7 +1021,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
 
        err = drv_start_ap(sdata->local, sdata);
        if (err) {
-               old = rtnl_dereference(sdata->u.ap.beacon);
+               old = sdata_dereference(sdata->u.ap.beacon, sdata);
+
                if (old)
                        kfree_rcu(old, rcu_head);
                RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
@@ -1032,7 +1053,7 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
        if (sdata->vif.csa_active)
                return -EBUSY;
 
-       old = rtnl_dereference(sdata->u.ap.beacon);
+       old = sdata_dereference(sdata->u.ap.beacon, sdata);
        if (!old)
                return -ENOENT;
 
@@ -1050,15 +1071,18 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
        struct ieee80211_local *local = sdata->local;
        struct beacon_data *old_beacon;
        struct probe_resp *old_probe_resp;
+       struct cfg80211_chan_def chandef;
 
-       old_beacon = rtnl_dereference(sdata->u.ap.beacon);
+       old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata);
        if (!old_beacon)
                return -ENOENT;
-       old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp);
+       old_probe_resp = sdata_dereference(sdata->u.ap.probe_resp, sdata);
 
        /* abort any running channel switch */
        sdata->vif.csa_active = false;
-       cancel_work_sync(&sdata->csa_finalize_work);
+       kfree(sdata->u.ap.next_beacon);
+       sdata->u.ap.next_beacon = NULL;
+
        cancel_work_sync(&sdata->u.ap.request_smps_work);
 
        /* turn off carrier for this interface and dependent VLANs */
@@ -1091,8 +1115,10 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
        ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
 
        if (sdata->wdev.cac_started) {
+               chandef = sdata->vif.bss_conf.chandef;
                cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
-               cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED,
+               cfg80211_cac_event(sdata->dev, &chandef,
+                                  NL80211_RADAR_CAC_ABORTED,
                                   GFP_KERNEL);
        }
 
@@ -1953,7 +1979,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
        enum ieee80211_band band;
        u32 changed = 0;
 
-       if (!rtnl_dereference(sdata->u.ap.beacon))
+       if (!sdata_dereference(sdata->u.ap.beacon, sdata))
                return -ENOENT;
 
        band = ieee80211_get_sdata_band(sdata);
@@ -2963,27 +2989,33 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
        struct ieee80211_local *local = sdata->local;
        int err, changed = 0;
 
+       sdata_lock(sdata);
+       /* AP might have been stopped while waiting for the lock. */
+       if (!sdata->vif.csa_active)
+               goto unlock;
+
        if (!ieee80211_sdata_running(sdata))
-               return;
+               goto unlock;
 
        sdata->radar_required = sdata->csa_radar_required;
-       err = ieee80211_vif_change_channel(sdata, &local->csa_chandef,
-                                          &changed);
+       err = ieee80211_vif_change_channel(sdata, &changed);
        if (WARN_ON(err < 0))
-               return;
+               goto unlock;
 
        if (!local->use_chanctx) {
-               local->_oper_chandef = local->csa_chandef;
+               local->_oper_chandef = sdata->csa_chandef;
                ieee80211_hw_config(local, 0);
        }
 
        ieee80211_bss_info_change_notify(sdata, changed);
 
+       sdata->vif.csa_active = false;
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_AP:
                err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
                if (err < 0)
-                       return;
+                       goto unlock;
+
                changed |= err;
                kfree(sdata->u.ap.next_beacon);
                sdata->u.ap.next_beacon = NULL;
@@ -2997,20 +3029,22 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
        case NL80211_IFTYPE_MESH_POINT:
                err = ieee80211_mesh_finish_csa(sdata);
                if (err < 0)
-                       return;
+                       goto unlock;
                break;
 #endif
        default:
                WARN_ON(1);
-               return;
+               goto unlock;
        }
-       sdata->vif.csa_active = false;
 
        ieee80211_wake_queues_by_reason(&sdata->local->hw,
                                        IEEE80211_MAX_QUEUE_MAP,
                                        IEEE80211_QUEUE_STOP_REASON_CSA);
 
-       cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef);
+       cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
+
+unlock:
+       sdata_unlock(sdata);
 }
 
 static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
@@ -3023,6 +3057,8 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
        struct ieee80211_if_mesh __maybe_unused *ifmsh;
        int err, num_chanctx;
 
+       lockdep_assert_held(&sdata->wdev.mtx);
+
        if (!list_empty(&local->roc_list) || local->scanning)
                return -EBUSY;
 
@@ -3143,7 +3179,7 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
                                IEEE80211_MAX_QUEUE_MAP,
                                IEEE80211_QUEUE_STOP_REASON_CSA);
 
-       local->csa_chandef = params->chandef;
+       sdata->csa_chandef = params->chandef;
        sdata->vif.csa_active = true;
 
        ieee80211_bss_info_change_notify(sdata, err);
@@ -3153,26 +3189,25 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
 }
 
 static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
-                            struct ieee80211_channel *chan, bool offchan,
-                            unsigned int wait, const u8 *buf, size_t len,
-                            bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+                            struct cfg80211_mgmt_tx_params *params,
+                            u64 *cookie)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
        struct sta_info *sta;
-       const struct ieee80211_mgmt *mgmt = (void *)buf;
+       const struct ieee80211_mgmt *mgmt = (void *)params->buf;
        bool need_offchan = false;
        u32 flags;
        int ret;
 
-       if (dont_wait_for_ack)
+       if (params->dont_wait_for_ack)
                flags = IEEE80211_TX_CTL_NO_ACK;
        else
                flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
                        IEEE80211_TX_CTL_REQ_TX_STATUS;
 
-       if (no_cck)
+       if (params->no_cck)
                flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
 
        switch (sdata->vif.type) {
@@ -3220,7 +3255,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
        /* configurations requiring offchan cannot work if no channel has been
         * specified
         */
-       if (need_offchan && !chan)
+       if (need_offchan && !params->chan)
                return -EINVAL;
 
        mutex_lock(&local->mtx);
@@ -3233,8 +3268,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
                chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
 
                if (chanctx_conf) {
-                       need_offchan = chan && (chan != chanctx_conf->def.chan);
-               } else if (!chan) {
+                       need_offchan = params->chan &&
+                                      (params->chan !=
+                                       chanctx_conf->def.chan);
+               } else if (!params->chan) {
                        ret = -EINVAL;
                        rcu_read_unlock();
                        goto out_unlock;
@@ -3244,19 +3281,19 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
                rcu_read_unlock();
        }
 
-       if (need_offchan && !offchan) {
+       if (need_offchan && !params->offchan) {
                ret = -EBUSY;
                goto out_unlock;
        }
 
-       skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
+       skb = dev_alloc_skb(local->hw.extra_tx_headroom + params->len);
        if (!skb) {
                ret = -ENOMEM;
                goto out_unlock;
        }
        skb_reserve(skb, local->hw.extra_tx_headroom);
 
-       memcpy(skb_put(skb, len), buf, len);
+       memcpy(skb_put(skb, params->len), params->buf, params->len);
 
        IEEE80211_SKB_CB(skb)->flags = flags;
 
@@ -3276,8 +3313,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
                        local->hw.offchannel_tx_hw_queue;
 
        /* This will handle all kinds of coalescing and immediate TX */
-       ret = ieee80211_start_roc_work(local, sdata, chan,
-                                      wait, cookie, skb,
+       ret = ieee80211_start_roc_work(local, sdata, params->chan,
+                                      params->wait, cookie, skb,
                                       IEEE80211_ROC_TYPE_MGMT_TX);
        if (ret)
                kfree_skb(skb);
index 03ba6b5c5373b373d47956518fafeaf1338b2ad0..a57d5d9466bcbca1c8aa05276502ede6987783e7 100644 (file)
@@ -9,6 +9,140 @@
 #include "ieee80211_i.h"
 #include "driver-ops.h"
 
+static enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta)
+{
+       switch (sta->bandwidth) {
+       case IEEE80211_STA_RX_BW_20:
+               if (sta->ht_cap.ht_supported)
+                       return NL80211_CHAN_WIDTH_20;
+               else
+                       return NL80211_CHAN_WIDTH_20_NOHT;
+       case IEEE80211_STA_RX_BW_40:
+               return NL80211_CHAN_WIDTH_40;
+       case IEEE80211_STA_RX_BW_80:
+               return NL80211_CHAN_WIDTH_80;
+       case IEEE80211_STA_RX_BW_160:
+               /*
+                * This applied for both 160 and 80+80. since we use
+                * the returned value to consider degradation of
+                * ctx->conf.min_def, we have to make sure to take
+                * the bigger one (NL80211_CHAN_WIDTH_160).
+                * Otherwise we might try degrading even when not
+                * needed, as the max required sta_bw returned (80+80)
+                * might be smaller than the configured bw (160).
+                */
+               return NL80211_CHAN_WIDTH_160;
+       default:
+               WARN_ON(1);
+               return NL80211_CHAN_WIDTH_20;
+       }
+}
+
+static enum nl80211_chan_width
+ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata)
+{
+       enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
+       struct sta_info *sta;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
+               if (sdata != sta->sdata &&
+                   !(sta->sdata->bss && sta->sdata->bss == sdata->bss))
+                       continue;
+
+               if (!sta->uploaded)
+                       continue;
+
+               max_bw = max(max_bw, ieee80211_get_sta_bw(&sta->sta));
+       }
+       rcu_read_unlock();
+
+       return max_bw;
+}
+
+static enum nl80211_chan_width
+ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
+                                     struct ieee80211_chanctx_conf *conf)
+{
+       struct ieee80211_sub_if_data *sdata;
+       enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+               struct ieee80211_vif *vif = &sdata->vif;
+               enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT;
+
+               if (!ieee80211_sdata_running(sdata))
+                       continue;
+
+               if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
+                       continue;
+
+               switch (vif->type) {
+               case NL80211_IFTYPE_AP:
+               case NL80211_IFTYPE_AP_VLAN:
+                       width = ieee80211_get_max_required_bw(sdata);
+                       break;
+               case NL80211_IFTYPE_P2P_DEVICE:
+                       continue;
+               case NL80211_IFTYPE_STATION:
+               case NL80211_IFTYPE_ADHOC:
+               case NL80211_IFTYPE_WDS:
+               case NL80211_IFTYPE_MESH_POINT:
+                       width = vif->bss_conf.chandef.width;
+                       break;
+               case NL80211_IFTYPE_UNSPECIFIED:
+               case NUM_NL80211_IFTYPES:
+               case NL80211_IFTYPE_MONITOR:
+               case NL80211_IFTYPE_P2P_CLIENT:
+               case NL80211_IFTYPE_P2P_GO:
+                       WARN_ON_ONCE(1);
+               }
+               max_bw = max(max_bw, width);
+       }
+       rcu_read_unlock();
+
+       return max_bw;
+}
+
+/*
+ * recalc the min required chan width of the channel context, which is
+ * the max of min required widths of all the interfaces bound to this
+ * channel context.
+ */
+void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
+                                     struct ieee80211_chanctx *ctx)
+{
+       enum nl80211_chan_width max_bw;
+       struct cfg80211_chan_def min_def;
+
+       lockdep_assert_held(&local->chanctx_mtx);
+
+       /* don't optimize 5MHz, 10MHz, and radar_enabled confs */
+       if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 ||
+           ctx->conf.def.width == NL80211_CHAN_WIDTH_10 ||
+           ctx->conf.radar_enabled) {
+               ctx->conf.min_def = ctx->conf.def;
+               return;
+       }
+
+       max_bw = ieee80211_get_chanctx_max_required_bw(local, &ctx->conf);
+
+       /* downgrade chandef up to max_bw */
+       min_def = ctx->conf.def;
+       while (min_def.width > max_bw)
+               ieee80211_chandef_downgrade(&min_def);
+
+       if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def))
+               return;
+
+       ctx->conf.min_def = min_def;
+       if (!ctx->driver_present)
+               return;
+
+       drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH);
+}
+
 static void ieee80211_change_chanctx(struct ieee80211_local *local,
                                     struct ieee80211_chanctx *ctx,
                                     const struct cfg80211_chan_def *chandef)
@@ -20,6 +154,7 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
 
        ctx->conf.def = *chandef;
        drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH);
+       ieee80211_recalc_chanctx_min_def(local, ctx);
 
        if (!local->use_chanctx) {
                local->_oper_chandef = *chandef;
@@ -93,6 +228,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
        ctx->conf.rx_chains_dynamic = 1;
        ctx->mode = mode;
        ctx->conf.radar_enabled = ieee80211_is_radar_required(local);
+       ieee80211_recalc_chanctx_min_def(local, ctx);
        if (!local->use_chanctx)
                local->hw.conf.radar_enabled = ctx->conf.radar_enabled;
 
@@ -179,6 +315,7 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
        ctx->refcount++;
 
        ieee80211_recalc_txpower(sdata);
+       ieee80211_recalc_chanctx_min_def(local, ctx);
        sdata->vif.bss_conf.idle = false;
 
        if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
@@ -243,6 +380,7 @@ static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
                ieee80211_recalc_chanctx_chantype(sdata->local, ctx);
                ieee80211_recalc_smps_chanctx(local, ctx);
                ieee80211_recalc_radar_chanctx(local, ctx);
+               ieee80211_recalc_chanctx_min_def(local, ctx);
        }
 }
 
@@ -411,12 +549,12 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
 }
 
 int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
-                                const struct cfg80211_chan_def *chandef,
                                 u32 *changed)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_chanctx_conf *conf;
        struct ieee80211_chanctx *ctx;
+       const struct cfg80211_chan_def *chandef = &sdata->csa_chandef;
        int ret;
        u32 chanctx_changed = 0;
 
@@ -456,6 +594,7 @@ int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
        ieee80211_recalc_chanctx_chantype(local, ctx);
        ieee80211_recalc_smps_chanctx(local, ctx);
        ieee80211_recalc_radar_chanctx(local, ctx);
+       ieee80211_recalc_chanctx_min_def(local, ctx);
 
        ret = 0;
  out:
index 5c090e41d9bbf1ea379307c8ecd6a648cb33f0ac..fa16e54980a1d3e76ce2f85fcb3253eb2599e838 100644 (file)
 
 #define DEBUGFS_FORMAT_BUFFER_SIZE 100
 
+#define TX_LATENCY_BIN_DELIMTER_C ','
+#define TX_LATENCY_BIN_DELIMTER_S ","
+#define TX_LATENCY_BINS_DISABLED "enable(bins disabled)\n"
+#define TX_LATENCY_DISABLED "disable\n"
+
+
+/*
+ * Display if Tx latency statistics & bins are enabled/disabled
+ */
+static ssize_t sta_tx_latency_stat_read(struct file *file,
+                                       char __user *userbuf,
+                                       size_t count, loff_t *ppos)
+{
+       struct ieee80211_local *local = file->private_data;
+       struct ieee80211_tx_latency_bin_ranges  *tx_latency;
+       char *buf;
+       int bufsz, i, ret;
+       int pos = 0;
+
+       rcu_read_lock();
+
+       tx_latency = rcu_dereference(local->tx_latency);
+
+       if (tx_latency && tx_latency->n_ranges) {
+               bufsz = tx_latency->n_ranges * 15;
+               buf = kzalloc(bufsz, GFP_ATOMIC);
+               if (!buf)
+                       goto err;
+
+               for (i = 0; i < tx_latency->n_ranges; i++)
+                       pos += scnprintf(buf + pos, bufsz - pos, "%d,",
+                                        tx_latency->ranges[i]);
+               pos += scnprintf(buf + pos, bufsz - pos, "\n");
+       } else if (tx_latency) {
+               bufsz = sizeof(TX_LATENCY_BINS_DISABLED) + 1;
+               buf = kzalloc(bufsz, GFP_ATOMIC);
+               if (!buf)
+                       goto err;
+
+               pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
+                                TX_LATENCY_BINS_DISABLED);
+       } else {
+               bufsz = sizeof(TX_LATENCY_DISABLED) + 1;
+               buf = kzalloc(bufsz, GFP_ATOMIC);
+               if (!buf)
+                       goto err;
+
+               pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
+                                TX_LATENCY_DISABLED);
+       }
+
+       rcu_read_unlock();
+
+       ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+       kfree(buf);
+
+       return ret;
+err:
+       rcu_read_unlock();
+       return -ENOMEM;
+}
+
+/*
+ * Receive input from user regarding Tx latency statistics
+ * The input should indicate if Tx latency statistics and bins are
+ * enabled/disabled.
+ * If bins are enabled input should indicate the amount of different bins and
+ * their ranges. Each bin will count how many Tx frames transmitted within the
+ * appropriate latency.
+ * Legal input is:
+ * a) "enable(bins disabled)" - to enable only general statistics
+ * b) "a,b,c,d,...z" - to enable general statistics and bins, where all are
+ * numbers and a < b < c < d.. < z
+ * c) "disable" - disable all statistics
+ * NOTE: must configure Tx latency statistics bins before stations connected.
+ */
+
+static ssize_t sta_tx_latency_stat_write(struct file *file,
+                                        const char __user *userbuf,
+                                        size_t count, loff_t *ppos)
+{
+       struct ieee80211_local *local = file->private_data;
+       char buf[128] = {};
+       char *bins = buf;
+       char *token;
+       int buf_size, i, alloc_size;
+       int prev_bin = 0;
+       int n_ranges = 0;
+       int ret = count;
+       struct ieee80211_tx_latency_bin_ranges  *tx_latency;
+
+       if (sizeof(buf) <= count)
+               return -EINVAL;
+       buf_size = count;
+       if (copy_from_user(buf, userbuf, buf_size))
+               return -EFAULT;
+
+       mutex_lock(&local->sta_mtx);
+
+       /* cannot change config once we have stations */
+       if (local->num_sta)
+               goto unlock;
+
+       tx_latency =
+               rcu_dereference_protected(local->tx_latency,
+                                         lockdep_is_held(&local->sta_mtx));
+
+       /* disable Tx statistics */
+       if (!strcmp(buf, TX_LATENCY_DISABLED)) {
+               if (!tx_latency)
+                       goto unlock;
+               rcu_assign_pointer(local->tx_latency, NULL);
+               synchronize_rcu();
+               kfree(tx_latency);
+               goto unlock;
+       }
+
+       /* Tx latency already enabled */
+       if (tx_latency)
+               goto unlock;
+
+       if (strcmp(TX_LATENCY_BINS_DISABLED, buf)) {
+               /* check how many bins and between what ranges user requested */
+               token = buf;
+               while (*token != '\0') {
+                       if (*token == TX_LATENCY_BIN_DELIMTER_C)
+                               n_ranges++;
+                       token++;
+               }
+               n_ranges++;
+       }
+
+       alloc_size = sizeof(struct ieee80211_tx_latency_bin_ranges) +
+                    n_ranges * sizeof(u32);
+       tx_latency = kzalloc(alloc_size, GFP_ATOMIC);
+       if (!tx_latency) {
+               ret = -ENOMEM;
+               goto unlock;
+       }
+       tx_latency->n_ranges = n_ranges;
+       for (i = 0; i < n_ranges; i++) { /* setting bin ranges */
+               token = strsep(&bins, TX_LATENCY_BIN_DELIMTER_S);
+               sscanf(token, "%d", &tx_latency->ranges[i]);
+               /* bins values should be in ascending order */
+               if (prev_bin >= tx_latency->ranges[i]) {
+                       ret = -EINVAL;
+                       kfree(tx_latency);
+                       goto unlock;
+               }
+               prev_bin = tx_latency->ranges[i];
+       }
+       rcu_assign_pointer(local->tx_latency, tx_latency);
+
+unlock:
+       mutex_unlock(&local->sta_mtx);
+
+       return ret;
+}
+
+static const struct file_operations stats_tx_latency_ops = {
+       .write = sta_tx_latency_stat_write,
+       .read = sta_tx_latency_stat_read,
+       .open = simple_open,
+       .llseek = generic_file_llseek,
+};
+
 int mac80211_format_buffer(char __user *userbuf, size_t count,
                                  loff_t *ppos, char *fmt, ...)
 {
@@ -315,4 +481,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
        DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount);
        DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount);
        DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount);
+
+       DEBUGFS_DEVSTATS_ADD(tx_latency);
 }
index 19c54a44ed4793823713b717a86111d4dda0d57d..80194b557a0cff8f3d2aba52f06cfc348212abf8 100644 (file)
@@ -38,6 +38,13 @@ static const struct file_operations sta_ ##name## _ops = {           \
        .llseek = generic_file_llseek,                                  \
 }
 
+#define STA_OPS_W(name)                                                        \
+static const struct file_operations sta_ ##name## _ops = {             \
+       .write = sta_##name##_write,                                    \
+       .open = simple_open,                                            \
+       .llseek = generic_file_llseek,                                  \
+}
+
 #define STA_OPS_RW(name)                                               \
 static const struct file_operations sta_ ##name## _ops = {             \
        .read = sta_##name##_read,                                      \
@@ -388,6 +395,131 @@ static ssize_t sta_last_rx_rate_read(struct file *file, char __user *userbuf,
 }
 STA_OPS(last_rx_rate);
 
+static int
+sta_tx_latency_stat_header(struct ieee80211_tx_latency_bin_ranges *tx_latency,
+                          char *buf, int pos, int bufsz)
+{
+       int i;
+       int range_count = tx_latency->n_ranges;
+       u32 *bin_ranges = tx_latency->ranges;
+
+       pos += scnprintf(buf + pos, bufsz - pos,
+                         "Station\t\t\tTID\tMax\tAvg");
+       if (range_count) {
+               pos += scnprintf(buf + pos, bufsz - pos,
+                                 "\t<=%d", bin_ranges[0]);
+               for (i = 0; i < range_count - 1; i++)
+                       pos += scnprintf(buf + pos, bufsz - pos, "\t%d-%d",
+                                         bin_ranges[i], bin_ranges[i+1]);
+               pos += scnprintf(buf + pos, bufsz - pos,
+                                 "\t%d<", bin_ranges[range_count - 1]);
+       }
+
+       pos += scnprintf(buf + pos, bufsz - pos, "\n");
+
+       return pos;
+}
+
+static int
+sta_tx_latency_stat_table(struct ieee80211_tx_latency_bin_ranges *tx_lat_range,
+                         struct ieee80211_tx_latency_stat *tx_lat,
+                         char *buf, int pos, int bufsz, int tid)
+{
+       u32 avg = 0;
+       int j;
+       int bin_count = tx_lat->bin_count;
+
+       pos += scnprintf(buf + pos, bufsz - pos, "\t\t\t%d", tid);
+       /* make sure you don't divide in 0 */
+       if (tx_lat->counter)
+               avg = tx_lat->sum / tx_lat->counter;
+
+       pos += scnprintf(buf + pos, bufsz - pos, "\t%d\t%d",
+                         tx_lat->max, avg);
+
+       if (tx_lat_range->n_ranges && tx_lat->bins)
+               for (j = 0; j < bin_count; j++)
+                       pos += scnprintf(buf + pos, bufsz - pos,
+                                         "\t%d", tx_lat->bins[j]);
+       pos += scnprintf(buf + pos, bufsz - pos, "\n");
+
+       return pos;
+}
+
+/*
+ * Output Tx latency statistics station && restart all statistics information
+ */
+static ssize_t sta_tx_latency_stat_read(struct file *file,
+                                       char __user *userbuf,
+                                       size_t count, loff_t *ppos)
+{
+       struct sta_info *sta = file->private_data;
+       struct ieee80211_local *local = sta->local;
+       struct ieee80211_tx_latency_bin_ranges *tx_latency;
+       char *buf;
+       int bufsz, ret, i;
+       int pos = 0;
+
+       bufsz = 20 * IEEE80211_NUM_TIDS *
+               sizeof(struct ieee80211_tx_latency_stat);
+       buf = kzalloc(bufsz, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       rcu_read_lock();
+
+       tx_latency = rcu_dereference(local->tx_latency);
+
+       if (!sta->tx_lat) {
+               pos += scnprintf(buf + pos, bufsz - pos,
+                                "Tx latency statistics are not enabled\n");
+               goto unlock;
+       }
+
+       pos = sta_tx_latency_stat_header(tx_latency, buf, pos, bufsz);
+
+       pos += scnprintf(buf + pos, bufsz - pos, "%pM\n", sta->sta.addr);
+       for (i = 0; i < IEEE80211_NUM_TIDS; i++)
+               pos = sta_tx_latency_stat_table(tx_latency, &sta->tx_lat[i],
+                                               buf, pos, bufsz, i);
+unlock:
+       rcu_read_unlock();
+
+       ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+       kfree(buf);
+
+       return ret;
+}
+STA_OPS(tx_latency_stat);
+
+static ssize_t sta_tx_latency_stat_reset_write(struct file *file,
+                                              const char __user *userbuf,
+                                              size_t count, loff_t *ppos)
+{
+       u32 *bins;
+       int bin_count;
+       struct sta_info *sta = file->private_data;
+       int i;
+
+       if (!sta->tx_lat)
+               return -EINVAL;
+
+       for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
+               bins = sta->tx_lat[i].bins;
+               bin_count = sta->tx_lat[i].bin_count;
+
+               sta->tx_lat[i].max = 0;
+               sta->tx_lat[i].sum = 0;
+               sta->tx_lat[i].counter = 0;
+
+               if (bin_count)
+                       memset(bins, 0, bin_count * sizeof(u32));
+       }
+
+       return count;
+}
+STA_OPS_W(tx_latency_stat_reset);
+
 #define DEBUGFS_ADD(name) \
        debugfs_create_file(#name, 0400, \
                sta->debugfs.dir, sta, &sta_ ##name## _ops);
@@ -441,6 +573,8 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
        DEBUGFS_ADD(last_ack_signal);
        DEBUGFS_ADD(current_tx_rate);
        DEBUGFS_ADD(last_rx_rate);
+       DEBUGFS_ADD(tx_latency_stat);
+       DEBUGFS_ADD(tx_latency_stat_reset);
 
        DEBUGFS_ADD_COUNTER(rx_packets, rx_packets);
        DEBUGFS_ADD_COUNTER(tx_packets, tx_packets);
index 27a39de89679b7d3710fea18a65b6d5df6d003d0..2eda7b13124abb7469a8b7b86503de07c0155623 100644 (file)
@@ -550,12 +550,12 @@ int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata)
                                        capability);
                /* XXX: should not really modify cfg80211 data */
                if (cbss) {
-                       cbss->channel = sdata->local->csa_chandef.chan;
+                       cbss->channel = sdata->csa_chandef.chan;
                        cfg80211_put_bss(sdata->local->hw.wiphy, cbss);
                }
        }
 
-       ifibss->chandef = sdata->local->csa_chandef;
+       ifibss->chandef = sdata->csa_chandef;
 
        /* generate the beacon */
        err = ieee80211_ibss_csa_beacon(sdata, NULL);
@@ -926,7 +926,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                                IEEE80211_MAX_QUEUE_MAP,
                                IEEE80211_QUEUE_STOP_REASON_CSA);
 
-       sdata->local->csa_chandef = params.chandef;
+       sdata->csa_chandef = params.chandef;
        sdata->vif.csa_active = true;
 
        ieee80211_bss_info_change_notify(sdata, err);
index 4aea4e7911135133818e66a1439b111d14e6147e..ed5bf8b4b5c2bfb8d4253a0dbaa15b76aac309dd 100644 (file)
@@ -728,6 +728,7 @@ struct ieee80211_sub_if_data {
        u16 sequence_number;
        __be16 control_port_protocol;
        bool control_port_no_encrypt;
+       int encrypt_headroom;
 
        struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
 
@@ -735,6 +736,7 @@ struct ieee80211_sub_if_data {
        int csa_counter_offset_beacon;
        int csa_counter_offset_presp;
        bool csa_radar_required;
+       struct cfg80211_chan_def csa_chandef;
 
        /* used to reconfigure hardware SM PS */
        struct work_struct recalc_smps;
@@ -811,6 +813,9 @@ static inline void sdata_unlock(struct ieee80211_sub_if_data *sdata)
        __release(&sdata->wdev.mtx);
 }
 
+#define sdata_dereference(p, sdata) \
+       rcu_dereference_protected(p, lockdep_is_held(&sdata->wdev.mtx))
+
 static inline void
 sdata_assert_lock(struct ieee80211_sub_if_data *sdata)
 {
@@ -896,6 +901,24 @@ struct tpt_led_trigger {
 };
 #endif
 
+/*
+ * struct ieee80211_tx_latency_bin_ranges - Tx latency statistics bins ranges
+ *
+ * Measuring Tx latency statistics. Counts how many Tx frames transmitted in a
+ * certain latency range (in Milliseconds). Each station that uses these
+ * ranges will have bins to count the amount of frames received in that range.
+ * The user can configure the ranges via debugfs.
+ * If ranges is NULL then Tx latency statistics bins are disabled for all
+ * stations.
+ *
+ * @n_ranges: number of ranges that are taken in account
+ * @ranges: the ranges that the user requested or NULL if disabled.
+ */
+struct ieee80211_tx_latency_bin_ranges {
+       int n_ranges;
+       u32 ranges[];
+};
+
 /**
  * mac80211 scan flags - currently active scan mode
  *
@@ -1048,6 +1071,12 @@ struct ieee80211_local {
        struct timer_list sta_cleanup;
        int sta_generation;
 
+       /*
+        * Tx latency statistics parameters for all stations.
+        * Can enable via debugfs (NULL when disabled).
+        */
+       struct ieee80211_tx_latency_bin_ranges __rcu *tx_latency;
+
        struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
        struct tasklet_struct tx_pending_tasklet;
 
@@ -1093,7 +1122,6 @@ struct ieee80211_local {
        enum mac80211_scan_state next_scan_state;
        struct delayed_work scan_work;
        struct ieee80211_sub_if_data __rcu *scan_sdata;
-       struct cfg80211_chan_def csa_chandef;
        /* For backward compatibility only -- do not use */
        struct cfg80211_chan_def _oper_chandef;
 
@@ -1693,6 +1721,7 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
 int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata,
                                enum ieee80211_smps_mode smps_mode);
 void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata);
+void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata);
 
 size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
                          const u8 *ids, int n_ids, size_t offset);
@@ -1731,7 +1760,6 @@ ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
 /* NOTE: only use ieee80211_vif_change_channel() for channel switch */
 int __must_check
 ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
-                            const struct cfg80211_chan_def *chandef,
                             u32 *changed);
 void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
 void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);
@@ -1742,6 +1770,8 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
                                   struct ieee80211_chanctx *chanctx);
 void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local,
                                    struct ieee80211_chanctx *chanctx);
+void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
+                                     struct ieee80211_chanctx *ctx);
 
 void ieee80211_dfs_cac_timer(unsigned long data);
 void ieee80211_dfs_cac_timer_work(struct work_struct *work);
@@ -1750,6 +1780,15 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work);
 int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
                              struct cfg80211_csa_settings *csa_settings);
 
+bool ieee80211_cs_valid(const struct ieee80211_cipher_scheme *cs);
+bool ieee80211_cs_list_valid(const struct ieee80211_cipher_scheme *cs, int n);
+const struct ieee80211_cipher_scheme *
+ieee80211_cs_get(struct ieee80211_local *local, u32 cipher,
+                enum nl80211_iftype iftype);
+int ieee80211_cs_headroom(struct ieee80211_local *local,
+                         struct cfg80211_crypto_settings *crypto,
+                         enum nl80211_iftype iftype);
+
 #ifdef CONFIG_MAC80211_NOINLINE
 #define debug_noinline noinline
 #else
index 36c3a4cbcabf66b2a0864414b3c23ea2896b7c4e..7aa9f9dea9df0af487c25c36d52004179d76b72c 100644 (file)
@@ -401,6 +401,8 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
        snprintf(sdata->name, IFNAMSIZ, "%s-monitor",
                 wiphy_name(local->hw.wiphy));
 
+       sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
+
        ieee80211_set_default_queues(sdata);
 
        ret = drv_add_interface(local, sdata);
@@ -749,6 +751,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        u32 hw_reconf_flags = 0;
        int i, flushed;
        struct ps_data *ps;
+       struct cfg80211_chan_def chandef;
 
        clear_bit(SDATA_STATE_RUNNING, &sdata->state);
 
@@ -823,11 +826,13 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
 
        if (sdata->wdev.cac_started) {
+               chandef = sdata->vif.bss_conf.chandef;
                WARN_ON(local->suspended);
                mutex_lock(&local->iflist_mtx);
                ieee80211_vif_release_channel(sdata);
                mutex_unlock(&local->iflist_mtx);
-               cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED,
+               cfg80211_cac_event(sdata->dev, &chandef,
+                                  NL80211_RADAR_CAC_ABORTED,
                                   GFP_KERNEL);
        }
 
@@ -1036,7 +1041,6 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
  */
 static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
 {
-       int flushed;
        int i;
 
        /* free extra data */
@@ -1050,9 +1054,6 @@ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
 
        if (ieee80211_vif_is_mesh(&sdata->vif))
                mesh_rmc_free(sdata);
-
-       flushed = sta_info_flush(sdata);
-       WARN_ON(flushed);
 }
 
 static void ieee80211_uninit(struct net_device *dev)
@@ -1270,6 +1271,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
 
        sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE);
        sdata->control_port_no_encrypt = false;
+       sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
 
        sdata->noack_map = 0;
 
@@ -1685,6 +1687,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
        sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
        sdata->user_power_level = local->user_power_level;
 
+       sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
+
        /* setup type-dependent data */
        ieee80211_setup_sdata(sdata, type);
 
index 3e51dd7d98b34aad114e6b927beae8e4ecdde9fb..e568d98167d0244e499e53c0b2a3aad1263b1ea0 100644 (file)
@@ -260,25 +260,29 @@ static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
        int idx;
        bool defunikey, defmultikey, defmgmtkey;
 
+       /* caller must provide at least one old/new */
+       if (WARN_ON(!new && !old))
+               return;
+
        if (new)
                list_add_tail(&new->list, &sdata->key_list);
 
-       if (sta && pairwise) {
-               rcu_assign_pointer(sta->ptk, new);
-       } else if (sta) {
-               if (old)
-                       idx = old->conf.keyidx;
-               else
-                       idx = new->conf.keyidx;
-               rcu_assign_pointer(sta->gtk[idx], new);
-       } else {
-               WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
+       WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
 
-               if (old)
-                       idx = old->conf.keyidx;
-               else
-                       idx = new->conf.keyidx;
+       if (old)
+               idx = old->conf.keyidx;
+       else
+               idx = new->conf.keyidx;
 
+       if (sta) {
+               if (pairwise) {
+                       rcu_assign_pointer(sta->ptk[idx], new);
+                       sta->ptk_idx = idx;
+               } else {
+                       rcu_assign_pointer(sta->gtk[idx], new);
+                       sta->gtk_idx = idx;
+               }
+       } else {
                defunikey = old &&
                        old == key_mtx_dereference(sdata->local,
                                                sdata->default_unicast_key);
@@ -312,9 +316,11 @@ static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
                list_del(&old->list);
 }
 
-struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
-                                         const u8 *key_data,
-                                         size_t seq_len, const u8 *seq)
+struct ieee80211_key *
+ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
+                   const u8 *key_data,
+                   size_t seq_len, const u8 *seq,
+                   const struct ieee80211_cipher_scheme *cs)
 {
        struct ieee80211_key *key;
        int i, j, err;
@@ -393,6 +399,18 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
                        return ERR_PTR(err);
                }
                break;
+       default:
+               if (cs) {
+                       size_t len = (seq_len > MAX_PN_LEN) ?
+                                               MAX_PN_LEN : seq_len;
+
+                       key->conf.iv_len = cs->hdr_len;
+                       key->conf.icv_len = cs->mic_len;
+                       for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++)
+                               for (j = 0; j < len; j++)
+                                       key->u.gen.rx_pn[i][j] =
+                                                       seq[len - j - 1];
+               }
        }
        memcpy(key->conf.key, key_data, key_len);
        INIT_LIST_HEAD(&key->list);
@@ -475,7 +493,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
        mutex_lock(&sdata->local->key_mtx);
 
        if (sta && pairwise)
-               old_key = key_mtx_dereference(sdata->local, sta->ptk);
+               old_key = key_mtx_dereference(sdata->local, sta->ptk[idx]);
        else if (sta)
                old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]);
        else
@@ -625,8 +643,10 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local,
                list_add(&key->list, &keys);
        }
 
-       key = key_mtx_dereference(local, sta->ptk);
-       if (key) {
+       for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+               key = key_mtx_dereference(local, sta->ptk[i]);
+               if (!key)
+                       continue;
                ieee80211_key_replace(key->sdata, key->sta,
                                key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
                                key, NULL);
@@ -877,7 +897,7 @@ ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
 
        key = ieee80211_key_alloc(keyconf->cipher, keyconf->keyidx,
                                  keyconf->keylen, keyconf->key,
-                                 0, NULL);
+                                 0, NULL, NULL);
        if (IS_ERR(key))
                return ERR_CAST(key);
 
index aaae0ed3700402433ae56244eb97baa2804aba5b..0aebb889cabae566d6f33e00e59a2f299c9baa69 100644 (file)
@@ -18,6 +18,7 @@
 
 #define NUM_DEFAULT_KEYS 4
 #define NUM_DEFAULT_MGMT_KEYS 2
+#define MAX_PN_LEN 16
 
 struct ieee80211_local;
 struct ieee80211_sub_if_data;
@@ -93,6 +94,10 @@ struct ieee80211_key {
                        u32 replays; /* dot11RSNAStatsCMACReplays */
                        u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
                } aes_cmac;
+               struct {
+                       /* generic cipher scheme */
+                       u8 rx_pn[IEEE80211_NUM_TIDS + 1][MAX_PN_LEN];
+               } gen;
        } u;
 
        /* number of times this key has been used */
@@ -113,9 +118,11 @@ struct ieee80211_key {
        struct ieee80211_key_conf conf;
 };
 
-struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
-                                         const u8 *key_data,
-                                         size_t seq_len, const u8 *seq);
+struct ieee80211_key *
+ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
+                   const u8 *key_data,
+                   size_t seq_len, const u8 *seq,
+                   const struct ieee80211_cipher_scheme *cs);
 /*
  * Insert a key into data structures (sdata, sta if necessary)
  * to make it used, free old key. On failure, also free the new key.
index 7d1c3ac48ed941866170afdf387def183690d612..fa34cd2344b98b9615a940a00e78363b494bc06c 100644 (file)
@@ -651,15 +651,14 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 }
 EXPORT_SYMBOL(ieee80211_alloc_hw);
 
-int ieee80211_register_hw(struct ieee80211_hw *hw)
+static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
 {
-       struct ieee80211_local *local = hw_to_local(hw);
-       int result, i;
-       enum ieee80211_band band;
-       int channels, max_bitrates;
-       bool supp_ht, supp_vht;
-       netdev_features_t feature_whitelist;
-       struct cfg80211_chan_def dflt_chandef = {};
+       bool have_wep = !(IS_ERR(local->wep_tx_tfm) ||
+                         IS_ERR(local->wep_rx_tfm));
+       bool have_mfp = local->hw.flags & IEEE80211_HW_MFP_CAPABLE;
+       const struct ieee80211_cipher_scheme *cs = local->hw.cipher_schemes;
+       int n_suites = 0, r = 0, w = 0;
+       u32 *suites;
        static const u32 cipher_suites[] = {
                /* keep WEP first, it may be removed below */
                WLAN_CIPHER_SUITE_WEP40,
@@ -671,6 +670,93 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
                WLAN_CIPHER_SUITE_AES_CMAC
        };
 
+       /* Driver specifies the ciphers, we have nothing to do... */
+       if (local->hw.wiphy->cipher_suites && have_wep)
+               return 0;
+
+       /* Set up cipher suites if driver relies on mac80211 cipher defs */
+       if (!local->hw.wiphy->cipher_suites && !cs) {
+               local->hw.wiphy->cipher_suites = cipher_suites;
+               local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
+               if (!have_mfp)
+                       local->hw.wiphy->n_cipher_suites--;
+
+               if (!have_wep) {
+                       local->hw.wiphy->cipher_suites += 2;
+                       local->hw.wiphy->n_cipher_suites -= 2;
+               }
+
+               return 0;
+       }
+
+       if (!local->hw.wiphy->cipher_suites) {
+               /*
+                * Driver specifies cipher schemes only
+                * We start counting ciphers defined by schemes, TKIP and CCMP
+                */
+               n_suites = local->hw.n_cipher_schemes + 2;
+
+               /* check if we have WEP40 and WEP104 */
+               if (have_wep)
+                       n_suites += 2;
+
+               /* check if we have AES_CMAC */
+               if (have_mfp)
+                       n_suites++;
+
+               suites = kmalloc(sizeof(u32) * n_suites, GFP_KERNEL);
+               if (!suites)
+                       return -ENOMEM;
+
+               suites[w++] = WLAN_CIPHER_SUITE_CCMP;
+               suites[w++] = WLAN_CIPHER_SUITE_TKIP;
+
+               if (have_wep) {
+                       suites[w++] = WLAN_CIPHER_SUITE_WEP40;
+                       suites[w++] = WLAN_CIPHER_SUITE_WEP104;
+               }
+
+               if (have_mfp)
+                       suites[w++] = WLAN_CIPHER_SUITE_AES_CMAC;
+
+               for (r = 0; r < local->hw.n_cipher_schemes; r++)
+                       suites[w++] = cs[r].cipher;
+       } else {
+               /* Driver provides cipher suites, but we need to exclude WEP */
+               suites = kmemdup(local->hw.wiphy->cipher_suites,
+                                sizeof(u32) * local->hw.wiphy->n_cipher_suites,
+                                GFP_KERNEL);
+               if (!suites)
+                       return -ENOMEM;
+
+               for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
+                       u32 suite = local->hw.wiphy->cipher_suites[r];
+
+                       if (suite == WLAN_CIPHER_SUITE_WEP40 ||
+                           suite == WLAN_CIPHER_SUITE_WEP104)
+                               continue;
+                       suites[w++] = suite;
+               }
+       }
+
+       local->hw.wiphy->cipher_suites = suites;
+       local->hw.wiphy->n_cipher_suites = w;
+       local->wiphy_ciphers_allocated = true;
+
+       return 0;
+}
+
+int ieee80211_register_hw(struct ieee80211_hw *hw)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
+       int result, i;
+       enum ieee80211_band band;
+       int channels, max_bitrates;
+       bool supp_ht, supp_vht;
+       netdev_features_t feature_whitelist;
+       struct cfg80211_chan_def dflt_chandef = {};
+
        if (hw->flags & IEEE80211_HW_QUEUE_CONTROL &&
            (local->hw.offchannel_tx_hw_queue == IEEE80211_INVAL_HW_QUEUE ||
             local->hw.offchannel_tx_hw_queue >= local->hw.queues))
@@ -851,43 +937,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        if (local->hw.wiphy->max_scan_ie_len)
                local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len;
 
-       /* Set up cipher suites unless driver already did */
-       if (!local->hw.wiphy->cipher_suites) {
-               local->hw.wiphy->cipher_suites = cipher_suites;
-               local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-               if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE))
-                       local->hw.wiphy->n_cipher_suites--;
-       }
-       if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) {
-               if (local->hw.wiphy->cipher_suites == cipher_suites) {
-                       local->hw.wiphy->cipher_suites += 2;
-                       local->hw.wiphy->n_cipher_suites -= 2;
-               } else {
-                       u32 *suites;
-                       int r, w = 0;
-
-                       /* Filter out WEP */
-
-                       suites = kmemdup(
-                               local->hw.wiphy->cipher_suites,
-                               sizeof(u32) * local->hw.wiphy->n_cipher_suites,
-                               GFP_KERNEL);
-                       if (!suites) {
-                               result = -ENOMEM;
-                               goto fail_wiphy_register;
-                       }
-                       for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
-                               u32 suite = local->hw.wiphy->cipher_suites[r];
-                               if (suite == WLAN_CIPHER_SUITE_WEP40 ||
-                                   suite == WLAN_CIPHER_SUITE_WEP104)
-                                       continue;
-                               suites[w++] = suite;
-                       }
-                       local->hw.wiphy->cipher_suites = suites;
-                       local->hw.wiphy->n_cipher_suites = w;
-                       local->wiphy_ciphers_allocated = true;
-               }
-       }
+       WARN_ON(!ieee80211_cs_list_valid(local->hw.cipher_schemes,
+                                        local->hw.n_cipher_schemes));
+
+       result = ieee80211_init_cipher_suites(local);
+       if (result < 0)
+               goto fail_wiphy_register;
 
        if (!local->ops->remain_on_channel)
                local->hw.wiphy->max_remain_on_channel_duration = 5000;
@@ -1090,6 +1145,8 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
                     ieee80211_free_ack_frame, NULL);
        idr_destroy(&local->ack_status_frames);
 
+       kfree(rcu_access_pointer(local->tx_latency));
+
        wiphy_free(local->hw.wiphy);
 }
 EXPORT_SYMBOL(ieee80211_free_hw);
index ba105257d03f1cffc4398f42c52e67b1e8d3eaaa..89df62b2b6896f05a2d3170bce62a40fff23cf8c 100644 (file)
@@ -674,8 +674,6 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
        rcu_read_lock();
        csa = rcu_dereference(ifmsh->csa);
        if (csa) {
-               __le16 pre_value;
-
                pos = skb_put(skb, 13);
                memset(pos, 0, 13);
                *pos++ = WLAN_EID_CHANNEL_SWITCH;
@@ -697,8 +695,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
                          WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
                put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos);
                pos += 2;
-               pre_value = cpu_to_le16(ifmsh->pre_value);
-               memcpy(pos, &pre_value, 2);
+               put_unaligned_le16(ifmsh->pre_value, pos);
                pos += 2;
        }
        rcu_read_unlock();
@@ -964,7 +961,7 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
                                IEEE80211_MAX_QUEUE_MAP,
                                IEEE80211_QUEUE_STOP_REASON_CSA);
 
-       sdata->local->csa_chandef = params.chandef;
+       sdata->csa_chandef = params.chandef;
        sdata->vif.csa_active = true;
 
        ieee80211_bss_info_change_notify(sdata, err);
index 2bc7fd2f787dd9546ac616e8c55340e1957eafb1..f39a19f9090fe0d91181b8cb4487dd928232d24b 100644 (file)
@@ -215,8 +215,6 @@ int mesh_rmc_check(struct ieee80211_sub_if_data *sdata,
 bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
                        struct ieee802_11_elems *ie);
 void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
-void mesh_mgmt_ies_add(struct ieee80211_sub_if_data *sdata,
-                      struct sk_buff *skb);
 int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
                         struct sk_buff *skb);
 int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata,
@@ -303,8 +301,8 @@ void mesh_mpath_table_grow(void);
 void mesh_mpp_table_grow(void);
 /* Mesh paths */
 int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
-                      u8 ttl, const u8 *target, __le32 target_sn,
-                      __le16 target_rcode, const u8 *ra);
+                      u8 ttl, const u8 *target, u32 target_sn,
+                      u16 target_rcode, const u8 *ra);
 void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
 void mesh_path_flush_pending(struct mesh_path *mpath);
 void mesh_path_tx_pending(struct mesh_path *mpath);
index 486819cd02cd7d03924e30d4e93f7ac201248b4c..f9514685d45a54802cb0f21dce0953ccbe9b78f4 100644 (file)
@@ -102,12 +102,11 @@ enum mpath_frame_type {
 static const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
 static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
-                                 const u8 *orig_addr, __le32 orig_sn,
+                                 const u8 *orig_addr, u32 orig_sn,
                                  u8 target_flags, const u8 *target,
-                                 __le32 target_sn, const u8 *da,
+                                 u32 target_sn, const u8 *da,
                                  u8 hop_count, u8 ttl,
-                                 __le32 lifetime, __le32 metric,
-                                 __le32 preq_id,
+                                 u32 lifetime, u32 metric, u32 preq_id,
                                  struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_local *local = sdata->local;
@@ -167,33 +166,33 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
        if (action == MPATH_PREP) {
                memcpy(pos, target, ETH_ALEN);
                pos += ETH_ALEN;
-               memcpy(pos, &target_sn, 4);
+               put_unaligned_le32(target_sn, pos);
                pos += 4;
        } else {
                if (action == MPATH_PREQ) {
-                       memcpy(pos, &preq_id, 4);
+                       put_unaligned_le32(preq_id, pos);
                        pos += 4;
                }
                memcpy(pos, orig_addr, ETH_ALEN);
                pos += ETH_ALEN;
-               memcpy(pos, &orig_sn, 4);
+               put_unaligned_le32(orig_sn, pos);
                pos += 4;
        }
-       memcpy(pos, &lifetime, 4);      /* interval for RANN */
+       put_unaligned_le32(lifetime, pos); /* interval for RANN */
        pos += 4;
-       memcpy(pos, &metric, 4);
+       put_unaligned_le32(metric, pos);
        pos += 4;
        if (action == MPATH_PREQ) {
                *pos++ = 1; /* destination count */
                *pos++ = target_flags;
                memcpy(pos, target, ETH_ALEN);
                pos += ETH_ALEN;
-               memcpy(pos, &target_sn, 4);
+               put_unaligned_le32(target_sn, pos);
                pos += 4;
        } else if (action == MPATH_PREP) {
                memcpy(pos, orig_addr, ETH_ALEN);
                pos += ETH_ALEN;
-               memcpy(pos, &orig_sn, 4);
+               put_unaligned_le32(orig_sn, pos);
                pos += 4;
        }
 
@@ -239,8 +238,8 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
  * frame directly but add it to the pending queue instead.
  */
 int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
-                      u8 ttl, const u8 *target, __le32 target_sn,
-                      __le16 target_rcode, const u8 *ra)
+                      u8 ttl, const u8 *target, u32 target_sn,
+                      u16 target_rcode, const u8 *ra)
 {
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
@@ -254,13 +253,13 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
                return -EAGAIN;
 
        skb = dev_alloc_skb(local->tx_headroom +
-                           IEEE80211_ENCRYPT_HEADROOM +
+                           sdata->encrypt_headroom +
                            IEEE80211_ENCRYPT_TAILROOM +
                            hdr_len +
                            2 + 15 /* PERR IE */);
        if (!skb)
                return -1;
-       skb_reserve(skb, local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM);
+       skb_reserve(skb, local->tx_headroom + sdata->encrypt_headroom);
        mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
        memset(mgmt, 0, hdr_len);
        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
@@ -293,9 +292,9 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
        pos++;
        memcpy(pos, target, ETH_ALEN);
        pos += ETH_ALEN;
-       memcpy(pos, &target_sn, 4);
+       put_unaligned_le32(target_sn, pos);
        pos += 4;
-       memcpy(pos, &target_rcode, 2);
+       put_unaligned_le16(target_rcode, pos);
 
        /* see note in function header */
        prepare_frame_for_deferred_tx(sdata, skb);
@@ -592,10 +591,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
                if (ttl != 0) {
                        mhwmp_dbg(sdata, "replying to the PREQ\n");
                        mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr,
-                               cpu_to_le32(orig_sn), 0, target_addr,
-                               cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
-                               cpu_to_le32(lifetime), cpu_to_le32(metric),
-                               0, sdata);
+                                              orig_sn, 0, target_addr,
+                                              target_sn, mgmt->sa, 0, ttl,
+                                              lifetime, metric, 0, sdata);
                } else {
                        ifmsh->mshstats.dropped_frames_ttl++;
                }
@@ -625,11 +623,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
                }
 
                mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
-                               cpu_to_le32(orig_sn), target_flags, target_addr,
-                               cpu_to_le32(target_sn), da,
-                               hopcount, ttl, cpu_to_le32(lifetime),
-                               cpu_to_le32(metric), cpu_to_le32(preq_id),
-                               sdata);
+                                      orig_sn, target_flags, target_addr,
+                                      target_sn, da, hopcount, ttl, lifetime,
+                                      metric, preq_id, sdata);
                if (!is_multicast_ether_addr(da))
                        ifmsh->mshstats.fwded_unicast++;
                else
@@ -695,11 +691,9 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
        target_sn = PREP_IE_TARGET_SN(prep_elem);
        orig_sn = PREP_IE_ORIG_SN(prep_elem);
 
-       mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
-               cpu_to_le32(orig_sn), 0, target_addr,
-               cpu_to_le32(target_sn), next_hop, hopcount,
-               ttl, cpu_to_le32(lifetime), cpu_to_le32(metric),
-               0, sdata);
+       mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, orig_sn, 0,
+                              target_addr, target_sn, next_hop, hopcount,
+                              ttl, lifetime, metric, 0, sdata);
        rcu_read_unlock();
 
        sdata->u.mesh.mshstats.fwded_unicast++;
@@ -750,8 +744,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
                        if (!ifmsh->mshcfg.dot11MeshForwarding)
                                goto endperr;
                        mesh_path_error_tx(sdata, ttl, target_addr,
-                                          cpu_to_le32(target_sn),
-                                          cpu_to_le16(target_rcode),
+                                          target_sn, target_rcode,
                                           broadcast_addr);
                } else
                        spin_unlock_bh(&mpath->state_lock);
@@ -847,11 +840,9 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
 
        if (ifmsh->mshcfg.dot11MeshForwarding) {
                mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
-                                      cpu_to_le32(orig_sn),
-                                      0, NULL, 0, broadcast_addr,
-                                      hopcount, ttl, cpu_to_le32(interval),
-                                      cpu_to_le32(metric + metric_txsta),
-                                      0, sdata);
+                                      orig_sn, 0, NULL, 0, broadcast_addr,
+                                      hopcount, ttl, interval,
+                                      metric + metric_txsta, 0, sdata);
        }
 
        rcu_read_unlock();
@@ -1049,11 +1040,9 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
 
        spin_unlock_bh(&mpath->state_lock);
        da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr;
-       mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr,
-                       cpu_to_le32(ifmsh->sn), target_flags, mpath->dst,
-                       cpu_to_le32(mpath->sn), da, 0,
-                       ttl, cpu_to_le32(lifetime), 0,
-                       cpu_to_le32(ifmsh->preq_id++), sdata);
+       mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, ifmsh->sn,
+                              target_flags, mpath->dst, mpath->sn, da, 0,
+                              ttl, lifetime, 0, ifmsh->preq_id++, sdata);
        mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout);
 
 enddiscovery:
@@ -1212,10 +1201,9 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
        switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) {
        case IEEE80211_PROACTIVE_RANN:
                mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
-                              cpu_to_le32(++ifmsh->sn),
-                              0, NULL, 0, broadcast_addr,
-                              0, ifmsh->mshcfg.element_ttl,
-                              cpu_to_le32(interval), 0, 0, sdata);
+                                      ++ifmsh->sn, 0, NULL, 0, broadcast_addr,
+                                      0, ifmsh->mshcfg.element_ttl,
+                                      interval, 0, 0, sdata);
                break;
        case IEEE80211_PROACTIVE_PREQ_WITH_PREP:
                flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG;
@@ -1224,11 +1212,10 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
                target_flags |= IEEE80211_PREQ_TO_FLAG |
                                IEEE80211_PREQ_USN_FLAG;
                mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr,
-                               cpu_to_le32(++ifmsh->sn), target_flags,
-                               (u8 *) broadcast_addr, 0, broadcast_addr,
-                               0, ifmsh->mshcfg.element_ttl,
-                               cpu_to_le32(interval),
-                               0, cpu_to_le32(ifmsh->preq_id++), sdata);
+                                      ++ifmsh->sn, target_flags,
+                                      (u8 *) broadcast_addr, 0, broadcast_addr,
+                                      0, ifmsh->mshcfg.element_ttl, interval,
+                                      0, ifmsh->preq_id++, sdata);
                break;
        default:
                mhwmp_dbg(sdata, "Proactive mechanism not supported\n");
index 89aacfd2756d627287ce4d381e7038d0b0ebdd5e..7d050ed6fe5a4ec879bc9711c088db8360154448 100644 (file)
@@ -722,7 +722,6 @@ void mesh_plink_broken(struct sta_info *sta)
        struct mpath_node *node;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        int i;
-       __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE);
 
        rcu_read_lock();
        tbl = rcu_dereference(mesh_paths);
@@ -736,9 +735,9 @@ void mesh_plink_broken(struct sta_info *sta)
                        ++mpath->sn;
                        spin_unlock_bh(&mpath->state_lock);
                        mesh_path_error_tx(sdata,
-                                          sdata->u.mesh.mshcfg.element_ttl,
-                                          mpath->dst, cpu_to_le32(mpath->sn),
-                                          reason, bcast);
+                               sdata->u.mesh.mshcfg.element_ttl,
+                               mpath->dst, mpath->sn,
+                               WLAN_REASON_MESH_PATH_DEST_UNREACHABLE, bcast);
                }
        }
        rcu_read_unlock();
index 4301aa5aa227c3d539cd0bf89bdf5b004679976a..cf83217103f9c91479cd4f3f1b97a2752af0c897 100644 (file)
 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
                                jiffies + HZ * t / 1000))
 
-/* We only need a valid sta if user configured a minimum rssi_threshold. */
-#define rssi_threshold_check(sta, sdata) \
-               (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
-               (sta && (s8) -ewma_read(&sta->avg_signal) > \
-               sdata->u.mesh.mshcfg.rssi_threshold))
-
 enum plink_event {
        PLINK_UNDEFINED,
        OPN_ACPT,
@@ -61,7 +55,17 @@ static const char * const mplevents[] = {
 
 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
                               enum ieee80211_self_protected_actioncode action,
-                              u8 *da, __le16 llid, __le16 plid, __le16 reason);
+                              u8 *da, u16 llid, u16 plid, u16 reason);
+
+
+/* We only need a valid sta if user configured a minimum rssi_threshold. */
+static bool rssi_threshold_check(struct ieee80211_sub_if_data *sdata,
+                                struct sta_info *sta)
+{
+       s32 rssi_threshold = sdata->u.mesh.mshcfg.rssi_threshold;
+       return rssi_threshold == 0 ||
+              (sta && (s8) -ewma_read(&sta->avg_signal) > rssi_threshold);
+}
 
 /**
  * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
@@ -242,7 +246,7 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
 
        spin_lock_bh(&sta->lock);
        changed = __mesh_plink_deactivate(sta);
-       sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED);
+       sta->reason = WLAN_REASON_MESH_PEER_CANCELED;
        mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
                            sta->sta.addr, sta->llid, sta->plid,
                            sta->reason);
@@ -253,7 +257,7 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
 
 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
                               enum ieee80211_self_protected_actioncode action,
-                              u8 *da, __le16 llid, __le16 plid, __le16 reason)
+                              u8 *da, u16 llid, u16 plid, u16 reason)
 {
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
@@ -279,7 +283,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
                            2 + 8 + /* peering IE */
                            sdata->u.mesh.ie_len);
        if (!skb)
-               return -1;
+               return err;
        info = IEEE80211_SKB_CB(skb);
        skb_reserve(skb, local->tx_headroom);
        mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
@@ -301,7 +305,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
                if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
                        /* AID */
                        pos = skb_put(skb, 2);
-                       memcpy(pos + 2, &plid, 2);
+                       put_unaligned_le16(plid, pos + 2);
                }
                if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
                    ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
@@ -343,14 +347,14 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
        *pos++ = ie_len;
        memcpy(pos, &peering_proto, 2);
        pos += 2;
-       memcpy(pos, &llid, 2);
+       put_unaligned_le16(llid, pos);
        pos += 2;
        if (include_plid) {
-               memcpy(pos, &plid, 2);
+               put_unaligned_le16(plid, pos);
                pos += 2;
        }
        if (action == WLAN_SP_MESH_PEERING_CLOSE) {
-               memcpy(pos, &reason, 2);
+               put_unaligned_le16(reason, pos);
                pos += 2;
        }
 
@@ -518,7 +522,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
            sta->plink_state == NL80211_PLINK_LISTEN &&
            sdata->u.mesh.accepting_plinks &&
            sdata->u.mesh.mshcfg.auto_open_plinks &&
-           rssi_threshold_check(sta, sdata))
+           rssi_threshold_check(sdata, sta))
                changed = mesh_plink_open(sta);
 
        ieee80211_mps_frame_release(sta, elems);
@@ -530,9 +534,10 @@ out:
 static void mesh_plink_timer(unsigned long data)
 {
        struct sta_info *sta;
-       __le16 llid, plid, reason;
+       u16 reason = 0;
        struct ieee80211_sub_if_data *sdata;
        struct mesh_config *mshcfg;
+       enum ieee80211_self_protected_actioncode action = 0;
 
        /*
         * This STA is valid because sta_info_destroy() will
@@ -553,9 +558,6 @@ static void mesh_plink_timer(unsigned long data)
        mpl_dbg(sta->sdata,
                "Mesh plink timer for %pM fired on state %s\n",
                sta->sta.addr, mplstates[sta->plink_state]);
-       reason = 0;
-       llid = sta->llid;
-       plid = sta->plid;
        sdata = sta->sdata;
        mshcfg = &sdata->u.mesh.mshcfg;
 
@@ -574,33 +576,31 @@ static void mesh_plink_timer(unsigned long data)
                                             rand % sta->plink_timeout;
                        ++sta->plink_retries;
                        mod_plink_timer(sta, sta->plink_timeout);
-                       spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
-                                           sta->sta.addr, llid, 0, 0);
+                       action = WLAN_SP_MESH_PEERING_OPEN;
                        break;
                }
-               reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES);
+               reason = WLAN_REASON_MESH_MAX_RETRIES;
                /* fall through on else */
        case NL80211_PLINK_CNF_RCVD:
                /* confirm timer */
                if (!reason)
-                       reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
+                       reason = WLAN_REASON_MESH_CONFIRM_TIMEOUT;
                sta->plink_state = NL80211_PLINK_HOLDING;
                mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
-               spin_unlock_bh(&sta->lock);
-               mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-                                   sta->sta.addr, llid, plid, reason);
+               action = WLAN_SP_MESH_PEERING_CLOSE;
                break;
        case NL80211_PLINK_HOLDING:
                /* holding timer */
                del_timer(&sta->plink_timer);
                mesh_plink_fsm_restart(sta);
-               spin_unlock_bh(&sta->lock);
                break;
        default:
-               spin_unlock_bh(&sta->lock);
                break;
        }
+       spin_unlock_bh(&sta->lock);
+       if (action)
+               mesh_plink_frame_tx(sdata, action, sta->sta.addr,
+                                   sta->llid, sta->plid, reason);
 }
 
 static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
@@ -612,9 +612,40 @@ static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
        add_timer(&sta->plink_timer);
 }
 
+static bool llid_in_use(struct ieee80211_sub_if_data *sdata,
+                       u16 llid)
+{
+       struct ieee80211_local *local = sdata->local;
+       bool in_use = false;
+       struct sta_info *sta;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(sta, &local->sta_list, list) {
+               if (!memcmp(&sta->llid, &llid, sizeof(llid))) {
+                       in_use = true;
+                       break;
+               }
+       }
+       rcu_read_unlock();
+
+       return in_use;
+}
+
+static u16 mesh_get_new_llid(struct ieee80211_sub_if_data *sdata)
+{
+       u16 llid;
+
+       do {
+               get_random_bytes(&llid, sizeof(llid));
+               /* for mesh PS we still only have the AID range for TIM bits */
+               llid = (llid % IEEE80211_MAX_AID) + 1;
+       } while (llid_in_use(sdata, llid));
+
+       return llid;
+}
+
 u32 mesh_plink_open(struct sta_info *sta)
 {
-       __le16 llid;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        u32 changed;
 
@@ -622,8 +653,7 @@ u32 mesh_plink_open(struct sta_info *sta)
                return 0;
 
        spin_lock_bh(&sta->lock);
-       get_random_bytes(&llid, 2);
-       sta->llid = llid;
+       sta->llid = mesh_get_new_llid(sdata);
        if (sta->plink_state != NL80211_PLINK_LISTEN &&
            sta->plink_state != NL80211_PLINK_BLOCKED) {
                spin_unlock_bh(&sta->lock);
@@ -640,7 +670,7 @@ u32 mesh_plink_open(struct sta_info *sta)
        changed = ieee80211_mps_local_status_update(sdata);
 
        mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
-                           sta->sta.addr, llid, 0, 0);
+                           sta->sta.addr, sta->llid, 0, 0);
        return changed;
 }
 
@@ -656,390 +686,147 @@ u32 mesh_plink_block(struct sta_info *sta)
        return changed;
 }
 
-
-void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
-                        struct ieee80211_mgmt *mgmt, size_t len,
-                        struct ieee80211_rx_status *rx_status)
+static void mesh_plink_close(struct ieee80211_sub_if_data *sdata,
+                            struct sta_info *sta,
+                            enum plink_event event)
 {
        struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
-       struct ieee802_11_elems elems;
-       struct sta_info *sta;
-       enum plink_event event;
-       enum ieee80211_self_protected_actioncode ftype;
-       size_t baselen;
-       bool matches_local = true;
-       u8 ie_len;
-       u8 *baseaddr;
-       u32 changed = 0;
-       __le16 plid, llid, reason;
-
-       /* need action_code, aux */
-       if (len < IEEE80211_MIN_ACTION_SIZE + 3)
-               return;
-
-       if (sdata->u.mesh.user_mpm)
-               /* userspace must register for these */
-               return;
-
-       if (is_multicast_ether_addr(mgmt->da)) {
-               mpl_dbg(sdata,
-                       "Mesh plink: ignore frame from multicast address\n");
-               return;
-       }
-
-       baseaddr = mgmt->u.action.u.self_prot.variable;
-       baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
-       if (mgmt->u.action.u.self_prot.action_code ==
-                                               WLAN_SP_MESH_PEERING_CONFIRM) {
-               baseaddr += 4;
-               baselen += 4;
-       }
-       ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems);
-
-       if (!elems.peering) {
-               mpl_dbg(sdata,
-                       "Mesh plink: missing necessary peer link ie\n");
-               return;
-       }
 
-       if (elems.rsn_len &&
-           sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
-               mpl_dbg(sdata,
-                       "Mesh plink: can't establish link with secure peer\n");
-               return;
-       }
+       u16 reason = (event == CLS_ACPT) ?
+                    WLAN_REASON_MESH_CLOSE : WLAN_REASON_MESH_CONFIG;
 
-       ftype = mgmt->u.action.u.self_prot.action_code;
-       ie_len = elems.peering_len;
-       if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
-           (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
-           (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
-                                                       && ie_len != 8)) {
-               mpl_dbg(sdata,
-                       "Mesh plink: incorrect plink ie length %d %d\n",
-                       ftype, ie_len);
-               return;
-       }
-
-       if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
-           (!elems.mesh_id || !elems.mesh_config)) {
-               mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
-               return;
-       }
-       /* Note the lines below are correct, the llid in the frame is the plid
-        * from the point of view of this host.
-        */
-       memcpy(&plid, PLINK_GET_LLID(elems.peering), 2);
-       if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
-           (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
-               memcpy(&llid, PLINK_GET_PLID(elems.peering), 2);
-
-       /* WARNING: Only for sta pointer, is dropped & re-acquired */
-       rcu_read_lock();
-
-       sta = sta_info_get(sdata, mgmt->sa);
-       if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) {
-               mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
-               rcu_read_unlock();
-               return;
-       }
-
-       if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
-           !rssi_threshold_check(sta, sdata)) {
-               mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
-                       mgmt->sa);
-               rcu_read_unlock();
-               return;
-       }
-
-       if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
-               mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
-               rcu_read_unlock();
-               return;
-       }
+       sta->reason = reason;
+       sta->plink_state = NL80211_PLINK_HOLDING;
+       mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
+}
 
-       if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
-               rcu_read_unlock();
-               return;
-       }
+static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
+                               struct sta_info *sta)
+{
+       struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
+       u32 changed = 0;
 
-       /* Now we will figure out the appropriate event... */
-       event = PLINK_UNDEFINED;
-       if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
-           !mesh_matches_local(sdata, &elems)) {
-               matches_local = false;
-               switch (ftype) {
-               case WLAN_SP_MESH_PEERING_OPEN:
-                       event = OPN_RJCT;
-                       break;
-               case WLAN_SP_MESH_PEERING_CONFIRM:
-                       event = CNF_RJCT;
-                       break;
-               default:
-                       break;
-               }
-       }
+       del_timer(&sta->plink_timer);
+       sta->plink_state = NL80211_PLINK_ESTAB;
+       changed |= mesh_plink_inc_estab_count(sdata);
+       changed |= mesh_set_ht_prot_mode(sdata);
+       changed |= mesh_set_short_slot_time(sdata);
+       mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", sta->sta.addr);
+       ieee80211_mps_sta_status_update(sta);
+       changed |= ieee80211_mps_set_sta_local_pm(sta, mshcfg->power_mode);
+       return changed;
+}
 
-       if (!sta && !matches_local) {
-               rcu_read_unlock();
-               reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
-               llid = 0;
-               mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-                                   mgmt->sa, llid, plid, reason);
-               return;
-       } else if (!sta) {
-               /* ftype == WLAN_SP_MESH_PEERING_OPEN */
-               if (!mesh_plink_free_count(sdata)) {
-                       mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
-                       rcu_read_unlock();
-                       return;
-               }
-               event = OPN_ACPT;
-       } else if (matches_local) {
-               switch (ftype) {
-               case WLAN_SP_MESH_PEERING_OPEN:
-                       if (!mesh_plink_free_count(sdata) ||
-                           (sta->plid && sta->plid != plid))
-                               event = OPN_IGNR;
-                       else
-                               event = OPN_ACPT;
-                       break;
-               case WLAN_SP_MESH_PEERING_CONFIRM:
-                       if (!mesh_plink_free_count(sdata) ||
-                           (sta->llid != llid || sta->plid != plid))
-                               event = CNF_IGNR;
-                       else
-                               event = CNF_ACPT;
-                       break;
-               case WLAN_SP_MESH_PEERING_CLOSE:
-                       if (sta->plink_state == NL80211_PLINK_ESTAB)
-                               /* Do not check for llid or plid. This does not
-                                * follow the standard but since multiple plinks
-                                * per sta are not supported, it is necessary in
-                                * order to avoid a livelock when MP A sees an
-                                * establish peer link to MP B but MP B does not
-                                * see it. This can be caused by a timeout in
-                                * B's peer link establishment or B beign
-                                * restarted.
-                                */
-                               event = CLS_ACPT;
-                       else if (sta->plid != plid)
-                               event = CLS_IGNR;
-                       else if (ie_len == 7 && sta->llid != llid)
-                               event = CLS_IGNR;
-                       else
-                               event = CLS_ACPT;
-                       break;
-               default:
-                       mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
-                       rcu_read_unlock();
-                       return;
-               }
-       }
+/**
+ * mesh_plink_fsm - step @sta MPM based on @event
+ *
+ * @sdata: interface
+ * @sta: mesh neighbor
+ * @event: peering event
+ *
+ * Return: changed MBSS flags
+ */
+static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
+                         struct sta_info *sta, enum plink_event event)
+{
+       struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
+       enum ieee80211_self_protected_actioncode action = 0;
+       u32 changed = 0;
 
-       if (event == OPN_ACPT) {
-               rcu_read_unlock();
-               /* allocate sta entry if necessary and update info */
-               sta = mesh_sta_info_get(sdata, mgmt->sa, &elems);
-               if (!sta) {
-                       mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
-                       rcu_read_unlock();
-                       return;
-               }
-       }
+       mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr,
+               mplstates[sta->plink_state], mplevents[event]);
 
-       mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa,
-                      mplstates[sta->plink_state], mplevents[event]);
-       reason = 0;
        spin_lock_bh(&sta->lock);
        switch (sta->plink_state) {
-               /* spin_unlock as soon as state is updated at each case */
        case NL80211_PLINK_LISTEN:
                switch (event) {
                case CLS_ACPT:
                        mesh_plink_fsm_restart(sta);
-                       spin_unlock_bh(&sta->lock);
                        break;
                case OPN_ACPT:
                        sta->plink_state = NL80211_PLINK_OPN_RCVD;
-                       sta->plid = plid;
-                       get_random_bytes(&llid, 2);
-                       sta->llid = llid;
+                       sta->llid = mesh_get_new_llid(sdata);
                        mesh_plink_timer_set(sta,
                                             mshcfg->dot11MeshRetryTimeout);
 
                        /* set the non-peer mode to active during peering */
                        changed |= ieee80211_mps_local_status_update(sdata);
-
-                       spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata,
-                                           WLAN_SP_MESH_PEERING_OPEN,
-                                           sta->sta.addr, llid, 0, 0);
-                       mesh_plink_frame_tx(sdata,
-                                           WLAN_SP_MESH_PEERING_CONFIRM,
-                                           sta->sta.addr, llid, plid, 0);
+                       action = WLAN_SP_MESH_PEERING_OPEN;
                        break;
                default:
-                       spin_unlock_bh(&sta->lock);
                        break;
                }
                break;
-
        case NL80211_PLINK_OPN_SNT:
                switch (event) {
                case OPN_RJCT:
                case CNF_RJCT:
-                       reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
                case CLS_ACPT:
-                       if (!reason)
-                               reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
-                       sta->reason = reason;
-                       sta->plink_state = NL80211_PLINK_HOLDING;
-                       if (!mod_plink_timer(sta,
-                                            mshcfg->dot11MeshHoldingTimeout))
-                               sta->ignore_plink_timer = true;
-
-                       llid = sta->llid;
-                       spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata,
-                                           WLAN_SP_MESH_PEERING_CLOSE,
-                                           sta->sta.addr, llid, plid, reason);
+                       mesh_plink_close(sdata, sta, event);
+                       action = WLAN_SP_MESH_PEERING_CLOSE;
                        break;
                case OPN_ACPT:
                        /* retry timer is left untouched */
                        sta->plink_state = NL80211_PLINK_OPN_RCVD;
-                       sta->plid = plid;
-                       llid = sta->llid;
-                       spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata,
-                                           WLAN_SP_MESH_PEERING_CONFIRM,
-                                           sta->sta.addr, llid, plid, 0);
+                       action = WLAN_SP_MESH_PEERING_CONFIRM;
                        break;
                case CNF_ACPT:
                        sta->plink_state = NL80211_PLINK_CNF_RCVD;
                        if (!mod_plink_timer(sta,
                                             mshcfg->dot11MeshConfirmTimeout))
                                sta->ignore_plink_timer = true;
-
-                       spin_unlock_bh(&sta->lock);
                        break;
                default:
-                       spin_unlock_bh(&sta->lock);
                        break;
                }
                break;
-
        case NL80211_PLINK_OPN_RCVD:
                switch (event) {
                case OPN_RJCT:
                case CNF_RJCT:
-                       reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
                case CLS_ACPT:
-                       if (!reason)
-                               reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
-                       sta->reason = reason;
-                       sta->plink_state = NL80211_PLINK_HOLDING;
-                       if (!mod_plink_timer(sta,
-                                            mshcfg->dot11MeshHoldingTimeout))
-                               sta->ignore_plink_timer = true;
-
-                       llid = sta->llid;
-                       spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-                                           sta->sta.addr, llid, plid, reason);
+                       mesh_plink_close(sdata, sta, event);
+                       action = WLAN_SP_MESH_PEERING_CLOSE;
                        break;
                case OPN_ACPT:
-                       llid = sta->llid;
-                       spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata,
-                                           WLAN_SP_MESH_PEERING_CONFIRM,
-                                           sta->sta.addr, llid, plid, 0);
+                       action = WLAN_SP_MESH_PEERING_CONFIRM;
                        break;
                case CNF_ACPT:
-                       del_timer(&sta->plink_timer);
-                       sta->plink_state = NL80211_PLINK_ESTAB;
-                       spin_unlock_bh(&sta->lock);
-                       changed |= mesh_plink_inc_estab_count(sdata);
-                       changed |= mesh_set_ht_prot_mode(sdata);
-                       changed |= mesh_set_short_slot_time(sdata);
-                       mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
-                               sta->sta.addr);
-                       ieee80211_mps_sta_status_update(sta);
-                       changed |= ieee80211_mps_set_sta_local_pm(sta,
-                                                      mshcfg->power_mode);
+                       changed |= mesh_plink_establish(sdata, sta);
                        break;
                default:
-                       spin_unlock_bh(&sta->lock);
                        break;
                }
                break;
-
        case NL80211_PLINK_CNF_RCVD:
                switch (event) {
                case OPN_RJCT:
                case CNF_RJCT:
-                       reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
                case CLS_ACPT:
-                       if (!reason)
-                               reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
-                       sta->reason = reason;
-                       sta->plink_state = NL80211_PLINK_HOLDING;
-                       if (!mod_plink_timer(sta,
-                                            mshcfg->dot11MeshHoldingTimeout))
-                               sta->ignore_plink_timer = true;
-
-                       llid = sta->llid;
-                       spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata,
-                                           WLAN_SP_MESH_PEERING_CLOSE,
-                                           sta->sta.addr, llid, plid, reason);
+                       mesh_plink_close(sdata, sta, event);
+                       action = WLAN_SP_MESH_PEERING_CLOSE;
                        break;
                case OPN_ACPT:
-                       del_timer(&sta->plink_timer);
-                       sta->plink_state = NL80211_PLINK_ESTAB;
-                       spin_unlock_bh(&sta->lock);
-                       changed |= mesh_plink_inc_estab_count(sdata);
-                       changed |= mesh_set_ht_prot_mode(sdata);
-                       changed |= mesh_set_short_slot_time(sdata);
-                       mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
-                               sta->sta.addr);
-                       mesh_plink_frame_tx(sdata,
-                                           WLAN_SP_MESH_PEERING_CONFIRM,
-                                           sta->sta.addr, llid, plid, 0);
-                       ieee80211_mps_sta_status_update(sta);
-                       changed |= ieee80211_mps_set_sta_local_pm(sta,
-                                                       mshcfg->power_mode);
+                       changed |= mesh_plink_establish(sdata, sta);
+                       action = WLAN_SP_MESH_PEERING_CONFIRM;
                        break;
                default:
-                       spin_unlock_bh(&sta->lock);
                        break;
                }
                break;
-
        case NL80211_PLINK_ESTAB:
                switch (event) {
                case CLS_ACPT:
-                       reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
-                       sta->reason = reason;
                        changed |= __mesh_plink_deactivate(sta);
-                       sta->plink_state = NL80211_PLINK_HOLDING;
-                       llid = sta->llid;
-                       mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
-                       spin_unlock_bh(&sta->lock);
                        changed |= mesh_set_ht_prot_mode(sdata);
                        changed |= mesh_set_short_slot_time(sdata);
-                       mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-                                           sta->sta.addr, llid, plid, reason);
+                       mesh_plink_close(sdata, sta, event);
+                       action = WLAN_SP_MESH_PEERING_CLOSE;
                        break;
                case OPN_ACPT:
-                       llid = sta->llid;
-                       spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata,
-                                           WLAN_SP_MESH_PEERING_CONFIRM,
-                                           sta->sta.addr, llid, plid, 0);
+                       action = WLAN_SP_MESH_PEERING_CONFIRM;
                        break;
                default:
-                       spin_unlock_bh(&sta->lock);
                        break;
                }
                break;
@@ -1049,32 +836,271 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
                        if (del_timer(&sta->plink_timer))
                                sta->ignore_plink_timer = 1;
                        mesh_plink_fsm_restart(sta);
-                       spin_unlock_bh(&sta->lock);
                        break;
                case OPN_ACPT:
                case CNF_ACPT:
                case OPN_RJCT:
                case CNF_RJCT:
-                       llid = sta->llid;
-                       reason = sta->reason;
-                       spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-                                           sta->sta.addr, llid, plid, reason);
+                       action = WLAN_SP_MESH_PEERING_CLOSE;
                        break;
                default:
-                       spin_unlock_bh(&sta->lock);
+                       break;
                }
                break;
        default:
                /* should not get here, PLINK_BLOCKED is dealt with at the
                 * beginning of the function
                 */
-               spin_unlock_bh(&sta->lock);
                break;
        }
+       spin_unlock_bh(&sta->lock);
+       if (action) {
+               mesh_plink_frame_tx(sdata, action, sta->sta.addr,
+                                   sta->llid, sta->plid, sta->reason);
+
+               /* also send confirm in open case */
+               if (action == WLAN_SP_MESH_PEERING_OPEN) {
+                       mesh_plink_frame_tx(sdata,
+                                           WLAN_SP_MESH_PEERING_CONFIRM,
+                                           sta->sta.addr, sta->llid,
+                                           sta->plid, 0);
+               }
+       }
+
+       return changed;
+}
+
+/*
+ * mesh_plink_get_event - get correct MPM event
+ *
+ * @sdata: interface
+ * @sta: peer, leave NULL if processing a frame from a new suitable peer
+ * @elems: peering management IEs
+ * @ftype: frame type
+ * @llid: peer's peer link ID
+ * @plid: peer's local link ID
+ *
+ * Return: new peering event for @sta, but PLINK_UNDEFINED should be treated as
+ * an error.
+ */
+static enum plink_event
+mesh_plink_get_event(struct ieee80211_sub_if_data *sdata,
+                    struct sta_info *sta,
+                    struct ieee802_11_elems *elems,
+                    enum ieee80211_self_protected_actioncode ftype,
+                    u16 llid, u16 plid)
+{
+       enum plink_event event = PLINK_UNDEFINED;
+       u8 ie_len = elems->peering_len;
+       bool matches_local;
+
+       matches_local = (ftype == WLAN_SP_MESH_PEERING_CLOSE ||
+                        mesh_matches_local(sdata, elems));
+
+       /* deny open request from non-matching peer */
+       if (!matches_local && !sta) {
+               event = OPN_RJCT;
+               goto out;
+       }
+
+       if (!sta) {
+               if (ftype != WLAN_SP_MESH_PEERING_OPEN) {
+                       mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
+                       goto out;
+               }
+               /* ftype == WLAN_SP_MESH_PEERING_OPEN */
+               if (!mesh_plink_free_count(sdata)) {
+                       mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
+                       goto out;
+               }
+       } else {
+               if (!test_sta_flag(sta, WLAN_STA_AUTH)) {
+                       mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
+                       goto out;
+               }
+               if (sta->plink_state == NL80211_PLINK_BLOCKED)
+                       goto out;
+       }
+
+       /* new matching peer */
+       if (!sta) {
+               event = OPN_ACPT;
+               goto out;
+       }
+
+       switch (ftype) {
+       case WLAN_SP_MESH_PEERING_OPEN:
+               if (!matches_local)
+                       event = OPN_RJCT;
+               if (!mesh_plink_free_count(sdata) ||
+                   (sta->plid && sta->plid != plid))
+                       event = OPN_IGNR;
+               else
+                       event = OPN_ACPT;
+               break;
+       case WLAN_SP_MESH_PEERING_CONFIRM:
+               if (!matches_local)
+                       event = CNF_RJCT;
+               if (!mesh_plink_free_count(sdata) ||
+                   (sta->llid != llid || sta->plid != plid))
+                       event = CNF_IGNR;
+               else
+                       event = CNF_ACPT;
+               break;
+       case WLAN_SP_MESH_PEERING_CLOSE:
+               if (sta->plink_state == NL80211_PLINK_ESTAB)
+                       /* Do not check for llid or plid. This does not
+                        * follow the standard but since multiple plinks
+                        * per sta are not supported, it is necessary in
+                        * order to avoid a livelock when MP A sees an
+                        * establish peer link to MP B but MP B does not
+                        * see it. This can be caused by a timeout in
+                        * B's peer link establishment or B beign
+                        * restarted.
+                        */
+                       event = CLS_ACPT;
+               else if (sta->plid != plid)
+                       event = CLS_IGNR;
+               else if (ie_len == 8 && sta->llid != llid)
+                       event = CLS_IGNR;
+               else
+                       event = CLS_ACPT;
+               break;
+       default:
+               mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
+               break;
+       }
+
+out:
+       return event;
+}
 
+static void
+mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
+                        struct ieee80211_mgmt *mgmt,
+                        struct ieee802_11_elems *elems)
+{
+
+       struct sta_info *sta;
+       enum plink_event event;
+       enum ieee80211_self_protected_actioncode ftype;
+       u32 changed = 0;
+       u8 ie_len = elems->peering_len;
+       __le16 _plid, _llid;
+       u16 plid, llid = 0;
+
+       if (!elems->peering) {
+               mpl_dbg(sdata,
+                       "Mesh plink: missing necessary peer link ie\n");
+               return;
+       }
+
+       if (elems->rsn_len &&
+           sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
+               mpl_dbg(sdata,
+                       "Mesh plink: can't establish link with secure peer\n");
+               return;
+       }
+
+       ftype = mgmt->u.action.u.self_prot.action_code;
+       if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
+           (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
+           (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
+                                                       && ie_len != 8)) {
+               mpl_dbg(sdata,
+                       "Mesh plink: incorrect plink ie length %d %d\n",
+                       ftype, ie_len);
+               return;
+       }
+
+       if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
+           (!elems->mesh_id || !elems->mesh_config)) {
+               mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
+               return;
+       }
+       /* Note the lines below are correct, the llid in the frame is the plid
+        * from the point of view of this host.
+        */
+       memcpy(&_plid, PLINK_GET_LLID(elems->peering), sizeof(__le16));
+       plid = le16_to_cpu(_plid);
+       if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
+           (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8)) {
+               memcpy(&_llid, PLINK_GET_PLID(elems->peering), sizeof(__le16));
+               llid = le16_to_cpu(_llid);
+       }
+
+       /* WARNING: Only for sta pointer, is dropped & re-acquired */
+       rcu_read_lock();
+
+       sta = sta_info_get(sdata, mgmt->sa);
+
+       if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
+           !rssi_threshold_check(sdata, sta)) {
+               mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
+                       mgmt->sa);
+               goto unlock_rcu;
+       }
+
+       /* Now we will figure out the appropriate event... */
+       event = mesh_plink_get_event(sdata, sta, elems, ftype, llid, plid);
+
+       if (event == OPN_ACPT) {
+               rcu_read_unlock();
+               /* allocate sta entry if necessary and update info */
+               sta = mesh_sta_info_get(sdata, mgmt->sa, elems);
+               if (!sta) {
+                       mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
+                       goto unlock_rcu;
+               }
+               sta->plid = plid;
+       } else if (!sta && event == OPN_RJCT) {
+               mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
+                                   mgmt->sa, 0, plid,
+                                   WLAN_REASON_MESH_CONFIG);
+               goto unlock_rcu;
+       } else if (!sta || event == PLINK_UNDEFINED) {
+               /* something went wrong */
+               goto unlock_rcu;
+       }
+
+       changed |= mesh_plink_fsm(sdata, sta, event);
+
+unlock_rcu:
        rcu_read_unlock();
 
        if (changed)
                ieee80211_mbss_info_change_notify(sdata, changed);
 }
+
+void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
+                        struct ieee80211_mgmt *mgmt, size_t len,
+                        struct ieee80211_rx_status *rx_status)
+{
+       struct ieee802_11_elems elems;
+       size_t baselen;
+       u8 *baseaddr;
+
+       /* need action_code, aux */
+       if (len < IEEE80211_MIN_ACTION_SIZE + 3)
+               return;
+
+       if (sdata->u.mesh.user_mpm)
+               /* userspace must register for these */
+               return;
+
+       if (is_multicast_ether_addr(mgmt->da)) {
+               mpl_dbg(sdata,
+                       "Mesh plink: ignore frame from multicast address\n");
+               return;
+       }
+
+       baseaddr = mgmt->u.action.u.self_prot.variable;
+       baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
+       if (mgmt->u.action.u.self_prot.action_code ==
+                                               WLAN_SP_MESH_PEERING_CONFIRM) {
+               baseaddr += 4;
+               baselen += 4;
+       }
+       ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems);
+       mesh_process_plink_frame(sdata, mgmt, &elems);
+}
index 0f79b78b5e86b45a6d7059de497b68b44944da09..2802f9d9279de1527927a88bc731489cc22613c7 100644 (file)
@@ -576,10 +576,9 @@ void ieee80211_mps_frame_release(struct sta_info *sta,
        int ac, buffer_local = 0;
        bool has_buffered = false;
 
-       /* TIM map only for LLID <= IEEE80211_MAX_AID */
        if (sta->plink_state == NL80211_PLINK_ESTAB)
                has_buffered = ieee80211_check_tim(elems->tim, elems->tim_len,
-                               le16_to_cpu(sta->llid) % IEEE80211_MAX_AID);
+                                                  sta->llid);
 
        if (has_buffered)
                mps_dbg(sta->sdata, "%pM indicates buffered frames\n",
index 05a256b38e245b64b26a4adb11023898bcd115e1..d1cf2d5534998957c13cfbd5ca23c630d7c9f6a7 100644 (file)
@@ -92,12 +92,20 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
        if (stype != IEEE80211_STYPE_BEACON)
                return;
 
-       /* The current tsf is a first approximation for the timestamp
-        * for the received beacon.  Further down we try to get a
-        * better value from the rx_status->mactime field if
-        * available. Also we have to call drv_get_tsf() before
-        * entering the rcu-read section.*/
-       t_r = drv_get_tsf(local, sdata);
+       /*
+        * Get time when timestamp field was received.  If we don't
+        * have rx timestamps, then use current tsf as an approximation.
+        * drv_get_tsf() must be called before entering the rcu-read
+        * section.
+        */
+       if (ieee80211_have_rx_timestamp(rx_status))
+               t_r = ieee80211_calculate_rx_timestamp(local, rx_status,
+                                                      24 + 12 +
+                                                      elems->total_len +
+                                                      FCS_LEN,
+                                                      24);
+       else
+               t_r = drv_get_tsf(local, sdata);
 
        rcu_read_lock();
        sta = sta_info_get(sdata, mgmt->sa);
@@ -117,14 +125,6 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
                goto no_sync;
        }
 
-       if (ieee80211_have_rx_timestamp(rx_status))
-               /* time when timestamp field was received */
-               t_r = ieee80211_calculate_rx_timestamp(local, rx_status,
-                                                      24 + 12 +
-                                                      elems->total_len +
-                                                      FCS_LEN,
-                                                      24);
-
        /* Timing offset calculation (see 13.13.2.2.2) */
        t_t = le64_to_cpu(mgmt->u.beacon.timestamp);
        sta->t_offset = t_t - t_r;
index b3a3ce316656ce8406859a3cdc325fa262e024a5..900ead344f5bd526fa5f9a54b438a8cae52012e6 100644 (file)
@@ -330,6 +330,16 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
        if (WARN_ON_ONCE(!sta))
                return -EINVAL;
 
+       /*
+        * if bss configuration changed store the new one -
+        * this may be applicable even if channel is identical
+        */
+       ht_opmode = le16_to_cpu(ht_oper->operation_mode);
+       if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
+               *changed |= BSS_CHANGED_HT;
+               sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
+       }
+
        chan = sdata->vif.bss_conf.chandef.chan;
        sband = local->hw.wiphy->bands[chan->band];
 
@@ -416,14 +426,6 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
                                         IEEE80211_RC_BW_CHANGED);
        }
 
-       ht_opmode = le16_to_cpu(ht_oper->operation_mode);
-
-       /* if bss configuration changed store the new one */
-       if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
-               *changed |= BSS_CHANGED_HT;
-               sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
-       }
-
        return 0;
 }
 
@@ -714,7 +716,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
        }
 
        /* if present, add any custom IEs that go before HT */
-       if (assoc_data->ie_len && assoc_data->ie) {
+       if (assoc_data->ie_len) {
                static const u8 before_ht[] = {
                        WLAN_EID_SSID,
                        WLAN_EID_SUPP_RATES,
@@ -748,7 +750,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
                                     &assoc_data->ap_vht_cap);
 
        /* if present, add any custom non-vendor IEs that go after HT */
-       if (assoc_data->ie_len && assoc_data->ie) {
+       if (assoc_data->ie_len) {
                noffset = ieee80211_ie_split_vendor(assoc_data->ie,
                                                    assoc_data->ie_len,
                                                    offset);
@@ -779,7 +781,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
        }
 
        /* add any remaining custom (i.e. vendor specific here) IEs */
-       if (assoc_data->ie_len && assoc_data->ie) {
+       if (assoc_data->ie_len) {
                noffset = assoc_data->ie_len;
                pos = skb_put(skb, noffset - offset);
                memcpy(pos, assoc_data->ie + offset, noffset - offset);
@@ -886,8 +888,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
        if (!ifmgd->associated)
                goto out;
 
-       ret = ieee80211_vif_change_channel(sdata, &local->csa_chandef,
-                                          &changed);
+       ret = ieee80211_vif_change_channel(sdata, &changed);
        if (ret) {
                sdata_info(sdata,
                           "vif channel switch failed, disconnecting\n");
@@ -897,7 +898,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
        }
 
        if (!local->use_chanctx) {
-               local->_oper_chandef = local->csa_chandef;
+               local->_oper_chandef = sdata->csa_chandef;
                /* Call "hw_config" only if doing sw channel switch.
                 * Otherwise update the channel directly
                 */
@@ -908,7 +909,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
        }
 
        /* XXX: shouldn't really modify cfg80211-owned data! */
-       ifmgd->associated->channel = local->csa_chandef.chan;
+       ifmgd->associated->channel = sdata->csa_chandef.chan;
 
        /* XXX: wait for a beacon first? */
        ieee80211_wake_queues_by_reason(&local->hw,
@@ -1035,7 +1036,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        }
        mutex_unlock(&local->chanctx_mtx);
 
-       local->csa_chandef = csa_ie.chandef;
+       sdata->csa_chandef = csa_ie.chandef;
 
        if (csa_ie.mode)
                ieee80211_stop_queues_by_reason(&local->hw,
@@ -1398,10 +1399,12 @@ void ieee80211_dfs_cac_timer_work(struct work_struct *work)
        struct ieee80211_sub_if_data *sdata =
                container_of(delayed_work, struct ieee80211_sub_if_data,
                             dfs_cac_timer_work);
+       struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chandef;
 
        ieee80211_vif_release_channel(sdata);
-
-       cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
+       cfg80211_cac_event(sdata->dev, &chandef,
+                          NL80211_RADAR_CAC_FINISHED,
+                          GFP_KERNEL);
 }
 
 /* MLME */
@@ -1745,6 +1748,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 
        ifmgd->flags = 0;
        ieee80211_vif_release_channel(sdata);
+
+       sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
 }
 
 void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -4191,6 +4196,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 
        sdata->control_port_protocol = req->crypto.control_port_ethertype;
        sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
+       sdata->encrypt_headroom = ieee80211_cs_headroom(local, &req->crypto,
+                                                       sdata->vif.type);
 
        /* kick off associate process */
 
index 505bc0dea074809f1532f322528e222a5052c061..b95e16c070813da22169679e8c5c1aa7e3ee0f1d 100644 (file)
@@ -54,6 +54,8 @@ static inline void rate_control_rate_init(struct sta_info *sta)
        struct ieee80211_supported_band *sband;
        struct ieee80211_chanctx_conf *chanctx_conf;
 
+       ieee80211_sta_set_rx_nss(sta);
+
        if (!ref)
                return;
 
@@ -67,8 +69,6 @@ static inline void rate_control_rate_init(struct sta_info *sta)
 
        sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
 
-       ieee80211_sta_set_rx_nss(sta);
-
        ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
                            priv_sta);
        rcu_read_unlock();
index 7fa1b36e620247ed5c14e97d54b2d72d7a0b43cb..d2f19f7e7091b6e6b9111702f19b02f612fdb52c 100644 (file)
@@ -422,10 +422,9 @@ init_sample_table(struct minstrel_sta_info *mi)
        memset(mi->sample_table, 0xff, SAMPLE_COLUMNS * mi->n_rates);
 
        for (col = 0; col < SAMPLE_COLUMNS; col++) {
+               prandom_bytes(rnd, sizeof(rnd));
                for (i = 0; i < mi->n_rates; i++) {
-                       get_random_bytes(rnd, sizeof(rnd));
                        new_idx = (i + rnd[i & 7]) % mi->n_rates;
-
                        while (SAMPLE_TBL(mi, new_idx, col) != 0xff)
                                new_idx = (new_idx + 1) % mi->n_rates;
 
index 4096ff6cc24fe8a5c3505411c5b232e0d800e050..d2ed18d82fe1dd1f55a2f5c13f319920bbb9b887 100644 (file)
@@ -135,7 +135,7 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi);
 static int
 minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate)
 {
-       return GROUP_IDX((rate->idx / MCS_GROUP_RATES) + 1,
+       return GROUP_IDX((rate->idx / 8) + 1,
                         !!(rate->flags & IEEE80211_TX_RC_SHORT_GI),
                         !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH));
 }
@@ -148,7 +148,7 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
 
        if (rate->flags & IEEE80211_TX_RC_MCS) {
                group = minstrel_ht_get_group_idx(rate);
-               idx = rate->idx % MCS_GROUP_RATES;
+               idx = rate->idx % 8;
        } else {
                group = MINSTREL_CCK_GROUP;
 
@@ -637,8 +637,7 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
                idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)];
                flags = 0;
        } else {
-               idx = index % MCS_GROUP_RATES +
-                     (group->streams - 1) * MCS_GROUP_RATES;
+               idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8;
                flags = IEEE80211_TX_RC_MCS | group->flags;
        }
 
@@ -702,12 +701,16 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
        if (!mi->sample_tries)
                return -1;
 
-       mg = &mi->groups[mi->sample_group];
+       sample_group = mi->sample_group;
+       mg = &mi->groups[sample_group];
        sample_idx = sample_table[mg->column][mg->index];
+       minstrel_next_sample_idx(mi);
+
+       if (!(mg->supported & BIT(sample_idx)))
+               return -1;
+
        mr = &mg->rates[sample_idx];
-       sample_group = mi->sample_group;
        sample_idx += sample_group * MCS_GROUP_RATES;
-       minstrel_next_sample_idx(mi);
 
        /*
         * Sampling might add some overhead (RTS, no aggregation)
@@ -818,7 +821,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
        }
 
        rate->idx = sample_idx % MCS_GROUP_RATES +
-                   (sample_group->streams - 1) * MCS_GROUP_RATES;
+                   (sample_group->streams - 1) * 8;
        rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags;
 }
 
@@ -1053,10 +1056,9 @@ init_sample_table(void)
 
        memset(sample_table, 0xff, sizeof(sample_table));
        for (col = 0; col < SAMPLE_COLUMNS; col++) {
+               prandom_bytes(rnd, sizeof(rnd));
                for (i = 0; i < MCS_GROUP_RATES; i++) {
-                       get_random_bytes(rnd, sizeof(rnd));
                        new_idx = (i + rnd[i]) % MCS_GROUP_RATES;
-
                        while (sample_table[col][new_idx] != 0xff)
                                new_idx = (new_idx + 1) % MCS_GROUP_RATES;
 
index df44a5ad827049f251dd255f47e5c06262f1eb77..3e7d793de0c3407180965bb785485fd361700560 100644 (file)
@@ -54,8 +54,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
                        int r = bitrates[j % 4];
                        p += sprintf(p, " %2u.%1uM", r / 10, r % 10);
                } else {
-                       p += sprintf(p, " MCS%-2u", (mg->streams - 1) *
-                                        MCS_GROUP_RATES + j);
+                       p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j);
                }
 
                tp = mr->cur_tp / 10;
index 2b0debb0422b91d89a0a7982b94726f3b9ceae11..2dfa755227339533d2c105313ba8ab4ea3ba67b5 100644 (file)
@@ -638,6 +638,27 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
        return le16_to_cpu(mmie->key_id);
 }
 
+static int iwl80211_get_cs_keyid(const struct ieee80211_cipher_scheme *cs,
+                                struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       __le16 fc;
+       int hdrlen;
+       u8 keyid;
+
+       fc = hdr->frame_control;
+       hdrlen = ieee80211_hdrlen(fc);
+
+       if (skb->len < hdrlen + cs->hdr_len)
+               return -EINVAL;
+
+       skb_copy_bits(skb, hdrlen + cs->key_idx_off, &keyid, 1);
+       keyid &= cs->key_idx_mask;
+       keyid >>= cs->key_idx_shift;
+
+       return keyid;
+}
+
 static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
@@ -729,9 +750,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata
        lockdep_assert_held(&tid_agg_rx->reorder_lock);
 
        while (ieee80211_sn_less(tid_agg_rx->head_seq_num, head_seq_num)) {
-               index = ieee80211_sn_sub(tid_agg_rx->head_seq_num,
-                                        tid_agg_rx->ssn) %
-                                                       tid_agg_rx->buf_size;
+               index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
                ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
                                                frames);
        }
@@ -757,8 +776,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
        lockdep_assert_held(&tid_agg_rx->reorder_lock);
 
        /* release the buffer until next missing frame */
-       index = ieee80211_sn_sub(tid_agg_rx->head_seq_num,
-                                tid_agg_rx->ssn) % tid_agg_rx->buf_size;
+       index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
        if (!tid_agg_rx->reorder_buf[index] &&
            tid_agg_rx->stored_mpdu_num) {
                /*
@@ -793,15 +811,11 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
        } else while (tid_agg_rx->reorder_buf[index]) {
                ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
                                                frames);
-               index = ieee80211_sn_sub(tid_agg_rx->head_seq_num,
-                                        tid_agg_rx->ssn) %
-                                                       tid_agg_rx->buf_size;
+               index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
        }
 
        if (tid_agg_rx->stored_mpdu_num) {
-               j = index = ieee80211_sn_sub(tid_agg_rx->head_seq_num,
-                                            tid_agg_rx->ssn) %
-                                                       tid_agg_rx->buf_size;
+               j = index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
 
                for (; j != (index - 1) % tid_agg_rx->buf_size;
                     j = (j + 1) % tid_agg_rx->buf_size) {
@@ -861,8 +875,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
 
        /* Now the new frame is always in the range of the reordering buffer */
 
-       index = ieee80211_sn_sub(mpdu_seq_num,
-                                tid_agg_rx->ssn) % tid_agg_rx->buf_size;
+       index = mpdu_seq_num % tid_agg_rx->buf_size;
 
        /* check if we already stored this frame */
        if (tid_agg_rx->reorder_buf[index]) {
@@ -1369,6 +1382,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
        struct ieee80211_key *sta_ptk = NULL;
        int mmie_keyidx = -1;
        __le16 fc;
+       const struct ieee80211_cipher_scheme *cs = NULL;
 
        /*
         * Key selection 101
@@ -1406,11 +1420,19 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
 
        /* start without a key */
        rx->key = NULL;
+       fc = hdr->frame_control;
 
-       if (rx->sta)
-               sta_ptk = rcu_dereference(rx->sta->ptk);
+       if (rx->sta) {
+               int keyid = rx->sta->ptk_idx;
 
-       fc = hdr->frame_control;
+               if (ieee80211_has_protected(fc) && rx->sta->cipher_scheme) {
+                       cs = rx->sta->cipher_scheme;
+                       keyid = iwl80211_get_cs_keyid(cs, rx->skb);
+                       if (unlikely(keyid < 0))
+                               return RX_DROP_UNUSABLE;
+               }
+               sta_ptk = rcu_dereference(rx->sta->ptk[keyid]);
+       }
 
        if (!ieee80211_has_protected(fc))
                mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
@@ -1472,6 +1494,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
                return RX_CONTINUE;
        } else {
                u8 keyid;
+
                /*
                 * The device doesn't give us the IV so we won't be
                 * able to look up the key. That's ok though, we
@@ -1487,15 +1510,21 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
 
                hdrlen = ieee80211_hdrlen(fc);
 
-               if (rx->skb->len < 8 + hdrlen)
-                       return RX_DROP_UNUSABLE; /* TODO: count this? */
+               if (cs) {
+                       keyidx = iwl80211_get_cs_keyid(cs, rx->skb);
 
-               /*
-                * no need to call ieee80211_wep_get_keyidx,
-                * it verifies a bunch of things we've done already
-                */
-               skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
-               keyidx = keyid >> 6;
+                       if (unlikely(keyidx < 0))
+                               return RX_DROP_UNUSABLE;
+               } else {
+                       if (rx->skb->len < 8 + hdrlen)
+                               return RX_DROP_UNUSABLE; /* TODO: count this? */
+                       /*
+                        * no need to call ieee80211_wep_get_keyidx,
+                        * it verifies a bunch of things we've done already
+                        */
+                       skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
+                       keyidx = keyid >> 6;
+               }
 
                /* check per-station GTK first, if multicast packet */
                if (is_multicast_ether_addr(hdr->addr1) && rx->sta)
@@ -1543,11 +1572,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
                result = ieee80211_crypto_aes_cmac_decrypt(rx);
                break;
        default:
-               /*
-                * We can reach here only with HW-only algorithms
-                * but why didn't it decrypt the frame?!
-                */
-               return RX_DROP_UNUSABLE;
+               result = ieee80211_crypto_hw_decrypt(rx);
        }
 
        /* the hdr variable is invalid after the decrypt handlers */
@@ -2057,7 +2082,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
        struct ieee80211_sub_if_data *sdata = rx->sdata;
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-       __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD);
        u16 q, hdrlen;
 
        hdr = (struct ieee80211_hdr *) skb->data;
@@ -2165,7 +2189,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
        } else {
                /* unable to resolve next hop */
                mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
-                                  fwd_hdr->addr3, 0, reason, fwd_hdr->addr2);
+                                  fwd_hdr->addr3, 0,
+                                  WLAN_REASON_MESH_PATH_NOFORWARD,
+                                  fwd_hdr->addr2);
                IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
                kfree_skb(fwd_skb);
                return RX_DROP_MONITOR;
index bcc4833d7542b91e1b754ed490d1dedcaee559c1..4d73c46df86262a385ad5fb9a5912c6a8168831e 100644 (file)
@@ -526,7 +526,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
                ieee80211_hw_config(local, 0);
 
                if ((req->channels[0]->flags &
-                    IEEE80211_CHAN_PASSIVE_SCAN) ||
+                    IEEE80211_CHAN_NO_IR) ||
                    !local->scan_req->n_ssids) {
                        next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
                } else {
@@ -572,7 +572,7 @@ ieee80211_scan_get_channel_time(struct ieee80211_channel *chan)
         * TODO: channel switching also consumes quite some time,
         * add that delay as well to get a better estimation
         */
-       if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+       if (chan->flags & IEEE80211_CHAN_NO_IR)
                return IEEE80211_PASSIVE_CHANNEL_TIME;
        return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME;
 }
@@ -696,7 +696,7 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
         *
         * In any case, it is not necessary for a passive scan.
         */
-       if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
+       if (chan->flags & IEEE80211_CHAN_NO_IR ||
            !local->scan_req->n_ssids) {
                *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
                local->next_scan_state = SCAN_DECISION;
@@ -881,7 +881,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
                                struct ieee80211_channel *tmp_ch =
                                    &local->hw.wiphy->bands[band]->channels[i];
 
-                               if (tmp_ch->flags & (IEEE80211_CHAN_NO_IBSS |
+                               if (tmp_ch->flags & (IEEE80211_CHAN_NO_IR |
                                                     IEEE80211_CHAN_DISABLED))
                                        continue;
 
@@ -895,7 +895,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
 
                local->int_scan_req->n_channels = n_ch;
        } else {
-               if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IBSS |
+               if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IR |
                                                IEEE80211_CHAN_DISABLED)))
                        goto unlock;
 
index 1eb66e26e49d0a02869ec5e5ff4789583e9760d1..8ed97f76c3cfade5f0986fa2d17c8275753b3c35 100644 (file)
@@ -266,9 +266,17 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
  */
 void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
 {
+       int i;
+
        if (sta->rate_ctrl)
                rate_control_free_sta(sta);
 
+       if (sta->tx_lat) {
+               for (i = 0; i < IEEE80211_NUM_TIDS; i++)
+                       kfree(sta->tx_lat[i].bins);
+               kfree(sta->tx_lat);
+       }
+
        sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
 
        kfree(sta);
@@ -333,6 +341,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
        struct timespec uptime;
+       struct ieee80211_tx_latency_bin_ranges *tx_latency;
        int i;
 
        sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
@@ -410,6 +419,31 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
                }
        }
 
+       rcu_read_lock();
+
+       tx_latency = rcu_dereference(local->tx_latency);
+       /* init stations Tx latency statistics && TID bins */
+       if (tx_latency)
+               sta->tx_lat = kzalloc(IEEE80211_NUM_TIDS *
+                                     sizeof(struct ieee80211_tx_latency_stat),
+                                     GFP_ATOMIC);
+
+       /*
+        * if Tx latency and bins are enabled and the previous allocation
+        * succeeded
+        */
+       if (tx_latency && tx_latency->n_ranges && sta->tx_lat)
+               for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
+                       /* size of bins is size of the ranges +1 */
+                       sta->tx_lat[i].bin_count =
+                               tx_latency->n_ranges + 1;
+                       sta->tx_lat[i].bins  = kcalloc(sta->tx_lat[i].bin_count,
+                                                      sizeof(u32),
+                                                      GFP_ATOMIC);
+               }
+
+       rcu_read_unlock();
+
        sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
 
        return sta;
@@ -507,6 +541,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
 
        set_sta_flag(sta, WLAN_STA_INSERTED);
 
+       ieee80211_recalc_min_chandef(sdata);
        ieee80211_sta_debugfs_add(sta);
        rate_control_add_sta_debugfs(sta);
 
@@ -630,8 +665,8 @@ void sta_info_recalc_tim(struct sta_info *sta)
 #ifdef CONFIG_MAC80211_MESH
        } else if (ieee80211_vif_is_mesh(&sta->sdata->vif)) {
                ps = &sta->sdata->u.mesh.ps;
-               /* TIM map only for PLID <= IEEE80211_MAX_AID */
-               id = le16_to_cpu(sta->plid) % IEEE80211_MAX_AID;
+               /* TIM map only for 1 <= PLID <= IEEE80211_MAX_AID */
+               id = sta->plid % (IEEE80211_MAX_AID + 1);
 #endif
        } else {
                return;
@@ -869,6 +904,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
 
        rate_control_remove_sta_debugfs(sta);
        ieee80211_sta_debugfs_remove(sta);
+       ieee80211_recalc_min_chandef(sdata);
 
        call_rcu(&sta->rcu_head, free_sta_rcu);
 
index 3ef06a26b9cb9feaddfd3d752dd9bd8ac971a11c..0218caf5c14a793ef14045da6c0db6a13781b259 100644 (file)
@@ -220,6 +220,25 @@ struct sta_ampdu_mlme {
        u8 dialog_token_allocator;
 };
 
+/*
+ * struct ieee80211_tx_latency_stat - Tx latency statistics
+ *
+ * Measures TX latency and jitter for a station per TID.
+ *
+ * @max: worst case latency
+ * @sum: sum of all latencies
+ * @counter: amount of Tx frames sent from interface
+ * @bins: each bin counts how many frames transmitted within a certain
+ * latency range. when disabled it is NULL.
+ * @bin_count: amount of bins.
+ */
+struct ieee80211_tx_latency_stat {
+       u32 max;
+       u32 sum;
+       u32 counter;
+       u32 *bins;
+       u32 bin_count;
+};
 
 /**
  * struct sta_info - STA information
@@ -231,8 +250,10 @@ struct sta_ampdu_mlme {
  * @hnext: hash table linked list pointer
  * @local: pointer to the global information
  * @sdata: virtual interface this station belongs to
- * @ptk: peer key negotiated with this station, if any
+ * @ptk: peer keys negotiated with this station, if any
+ * @ptk_idx: last installed peer key index
  * @gtk: group keys negotiated with this station, if any
+ * @gtk_idx: last installed group key index
  * @rate_ctrl: rate control algorithm reference
  * @rate_ctrl_priv: rate control private per-STA pointer
  * @last_tx_rate: rate used for last transmit, to report to userspace as
@@ -274,6 +295,7 @@ struct sta_ampdu_mlme {
  * @tid_seq: per-TID sequence numbers for sending to this STA
  * @ampdu_mlme: A-MPDU state machine state
  * @timer_to_tid: identity mapping to ID timers
+ * @tx_lat: Tx latency statistics
  * @llid: Local link ID
  * @plid: Peer link ID
  * @reason: Cancel reason on PLINK_HOLDING state
@@ -303,6 +325,7 @@ struct sta_ampdu_mlme {
  * @chain_signal_avg: signal average (per chain)
  * @known_smps_mode: the smps_mode the client thinks we are in. Relevant for
  *     AP only.
+ * @cipher_scheme: optional cipher scheme for this station
  */
 struct sta_info {
        /* General information, mostly static */
@@ -312,7 +335,9 @@ struct sta_info {
        struct ieee80211_local *local;
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
-       struct ieee80211_key __rcu *ptk;
+       struct ieee80211_key __rcu *ptk[NUM_DEFAULT_KEYS];
+       u8 gtk_idx;
+       u8 ptk_idx;
        struct rate_control_ref *rate_ctrl;
        void *rate_ctrl_priv;
        spinlock_t lock;
@@ -380,14 +405,16 @@ struct sta_info {
        struct sta_ampdu_mlme ampdu_mlme;
        u8 timer_to_tid[IEEE80211_NUM_TIDS];
 
+       struct ieee80211_tx_latency_stat *tx_lat;
+
 #ifdef CONFIG_MAC80211_MESH
        /*
         * Mesh peer link attributes
         * TODO: move to a sub-structure that is referenced with pointer?
         */
-       __le16 llid;
-       __le16 plid;
-       __le16 reason;
+       u16 llid;
+       u16 plid;
+       u16 reason;
        u8 plink_retries;
        bool ignore_plink_timer;
        enum nl80211_plink_state plink_state;
@@ -414,6 +441,7 @@ struct sta_info {
        unsigned int beacon_loss_count;
 
        enum ieee80211_smps_mode known_smps_mode;
+       const struct ieee80211_cipher_scheme *cipher_scheme;
 
        /* keep last! */
        struct ieee80211_sta sta;
index 52a152b01b063b226fb5a523b19a4e9863eeffaf..1ee85c402439bfc886029f9ae6dfe6ec306e013f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/export.h>
 #include <linux/etherdevice.h>
+#include <linux/time.h>
 #include <net/mac80211.h>
 #include <asm/unaligned.h>
 #include "ieee80211_i.h"
@@ -462,6 +463,77 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
        }
 }
 
+/*
+ * Measure Tx frame completion and removal time for Tx latency statistics
+ * calculation. A single Tx frame latency should be measured from when it
+ * is entering the Kernel until we receive Tx complete confirmation indication
+ * and remove the skb.
+ */
+static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local,
+                                           struct sk_buff *skb,
+                                           struct sta_info *sta,
+                                           struct ieee80211_hdr *hdr)
+{
+       ktime_t skb_dprt;
+       struct timespec dprt_time;
+       u32 msrmnt;
+       u16 tid;
+       u8 *qc;
+       int i, bin_range_count, bin_count;
+       u32 *bin_ranges;
+       __le16 fc;
+       struct ieee80211_tx_latency_stat *tx_lat;
+       struct ieee80211_tx_latency_bin_ranges *tx_latency;
+       ktime_t skb_arv = skb->tstamp;
+
+       tx_latency = rcu_dereference(local->tx_latency);
+
+       /* assert Tx latency stats are enabled & frame arrived when enabled */
+       if (!tx_latency || !ktime_to_ns(skb_arv))
+               return;
+
+       fc = hdr->frame_control;
+
+       if (!ieee80211_is_data(fc)) /* make sure it is a data frame */
+               return;
+
+       /* get frame tid */
+       if (ieee80211_is_data_qos(hdr->frame_control)) {
+               qc = ieee80211_get_qos_ctl(hdr);
+               tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+       } else {
+               tid = 0;
+       }
+
+       tx_lat = &sta->tx_lat[tid];
+
+       ktime_get_ts(&dprt_time); /* time stamp completion time */
+       skb_dprt = ktime_set(dprt_time.tv_sec, dprt_time.tv_nsec);
+       msrmnt = ktime_to_ms(ktime_sub(skb_dprt, skb_arv));
+
+       if (tx_lat->max < msrmnt) /* update stats */
+               tx_lat->max = msrmnt;
+       tx_lat->counter++;
+       tx_lat->sum += msrmnt;
+
+       if (!tx_lat->bins) /* bins not activated */
+               return;
+
+       /* count how many Tx frames transmitted with the appropriate latency */
+       bin_range_count = tx_latency->n_ranges;
+       bin_ranges = tx_latency->ranges;
+       bin_count = tx_lat->bin_count;
+
+       for (i = 0; i < bin_range_count; i++) {
+               if (msrmnt <= bin_ranges[i]) {
+                       tx_lat->bins[i]++;
+                       break;
+               }
+       }
+       if (i == bin_range_count) /* msrmnt is bigger than the biggest range */
+               tx_lat->bins[i]++;
+}
+
 /*
  * Use a static threshold for now, best value to be determined
  * by testing ...
@@ -620,6 +692,12 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 
                if (acked)
                        sta->last_ack_signal = info->status.ack_signal;
+
+               /*
+                * Measure frame removal for tx latency
+                * statistics calculation
+                */
+               ieee80211_tx_latency_end_msrmnt(local, skb, sta, hdr);
        }
 
        rcu_read_unlock();
index d4cee98533fdc5a532a8ba74e48d6158faeb5003..e9ccf22f6dd972c8b0517c5d35a345085eb45ec6 100644 (file)
 #define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width,                     \
                        __entry->center_freq1, __entry->center_freq2
 
+#define MIN_CHANDEF_ENTRY                                                              \
+                       __field(u32, min_control_freq)                                  \
+                       __field(u32, min_chan_width)                                    \
+                       __field(u32, min_center_freq1)                                  \
+                       __field(u32, min_center_freq2)
+
+#define MIN_CHANDEF_ASSIGN(c)                                                          \
+                       __entry->min_control_freq = (c)->chan ? (c)->chan->center_freq : 0;     \
+                       __entry->min_chan_width = (c)->width;                           \
+                       __entry->min_center_freq1 = (c)->center_freq1;                  \
+                       __entry->min_center_freq2 = (c)->center_freq2;
+#define MIN_CHANDEF_PR_FMT     " min_control:%d MHz min_width:%d min_center: %d/%d MHz"
+#define MIN_CHANDEF_PR_ARG     __entry->min_control_freq, __entry->min_chan_width,     \
+                       __entry->min_center_freq1, __entry->min_center_freq2
+
 #define CHANCTX_ENTRY  CHANDEF_ENTRY                                                   \
+                       MIN_CHANDEF_ENTRY                                               \
                        __field(u8, rx_chains_static)                                   \
                        __field(u8, rx_chains_dynamic)
 #define CHANCTX_ASSIGN CHANDEF_ASSIGN(&ctx->conf.def)                                  \
+                       MIN_CHANDEF_ASSIGN(&ctx->conf.min_def)                          \
                        __entry->rx_chains_static = ctx->conf.rx_chains_static;         \
                        __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic
-#define CHANCTX_PR_FMT CHANDEF_PR_FMT " chains:%d/%d"
-#define CHANCTX_PR_ARG CHANDEF_PR_ARG,                                                 \
+#define CHANCTX_PR_FMT CHANDEF_PR_FMT MIN_CHANDEF_PR_FMT " chains:%d/%d"
+#define CHANCTX_PR_ARG CHANDEF_PR_ARG, MIN_CHANDEF_PR_ARG,                             \
                        __entry->rx_chains_static, __entry->rx_chains_dynamic
 
 
index c558b246ef0036c38e6c8a00b338b43c46913f78..6d59e21cdb9fe8b686fdcef53ddc83a83738d0cf 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/bitmap.h>
 #include <linux/rcupdate.h>
 #include <linux/export.h>
+#include <linux/time.h>
 #include <net/net_namespace.h>
 #include <net/ieee80211_radiotap.h>
 #include <net/cfg80211.h>
@@ -557,7 +558,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
 
        if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
                tx->key = NULL;
-       else if (tx->sta && (key = rcu_dereference(tx->sta->ptk)))
+       else if (tx->sta &&
+                (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
                tx->key = key;
        else if (ieee80211_is_mgmt(hdr->frame_control) &&
                 is_multicast_ether_addr(hdr->addr1) &&
@@ -840,15 +842,16 @@ static int ieee80211_fragment(struct ieee80211_tx_data *tx,
                rem -= fraglen;
                tmp = dev_alloc_skb(local->tx_headroom +
                                    frag_threshold +
-                                   IEEE80211_ENCRYPT_HEADROOM +
+                                   tx->sdata->encrypt_headroom +
                                    IEEE80211_ENCRYPT_TAILROOM);
                if (!tmp)
                        return -ENOMEM;
 
                __skb_queue_tail(&tx->skbs, tmp);
 
-               skb_reserve(tmp, local->tx_headroom +
-                                IEEE80211_ENCRYPT_HEADROOM);
+               skb_reserve(tmp,
+                           local->tx_headroom + tx->sdata->encrypt_headroom);
+
                /* copy control information */
                memcpy(tmp->cb, skb->cb, sizeof(tmp->cb));
 
@@ -1485,7 +1488,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
 
        headroom = local->tx_headroom;
        if (may_encrypt)
-               headroom += IEEE80211_ENCRYPT_HEADROOM;
+               headroom += sdata->encrypt_headroom;
        headroom -= skb_headroom(skb);
        headroom = max_t(int, 0, headroom);
 
@@ -1724,8 +1727,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
         * radar detection by itself. We can do that later by adding a
         * monitor flag interfaces used for AP support.
         */
-       if ((chan->flags & (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_RADAR |
-                           IEEE80211_CHAN_PASSIVE_SCAN)))
+       if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR)))
                goto fail_rcu;
 
        ieee80211_xmit(sdata, skb, chan->band);
@@ -1740,6 +1742,26 @@ fail:
        return NETDEV_TX_OK; /* meaning, we dealt with the skb */
 }
 
+/*
+ * Measure Tx frame arrival time for Tx latency statistics calculation
+ * A single Tx frame latency should be measured from when it is entering the
+ * Kernel until we receive Tx complete confirmation indication and the skb is
+ * freed.
+ */
+static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local,
+                                             struct sk_buff *skb)
+{
+       struct timespec skb_arv;
+       struct ieee80211_tx_latency_bin_ranges *tx_latency;
+
+       tx_latency = rcu_dereference(local->tx_latency);
+       if (!tx_latency)
+               return;
+
+       ktime_get_ts(&skb_arv);
+       skb->tstamp = ktime_set(skb_arv.tv_sec, skb_arv.tv_nsec);
+}
+
 /**
  * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type
  * subinterfaces (wlan#, WDS, and VLAN interfaces)
@@ -1790,6 +1812,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 
        rcu_read_lock();
 
+       /* Measure frame arrival for Tx latency statistics calculation */
+       ieee80211_tx_latency_start_msrmnt(local, skb);
+
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_AP_VLAN:
                sta = rcu_dereference(sdata->u.vlan.sta);
@@ -2109,7 +2134,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
         */
 
        if (head_need > 0 || skb_cloned(skb)) {
-               head_need += IEEE80211_ENCRYPT_HEADROOM;
+               head_need += sdata->encrypt_headroom;
                head_need += local->tx_headroom;
                head_need = max_t(int, 0, head_need);
                if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
index 9f9b9bd3fd44798e7030fb3a44c46da962cfd7ba..875e172c001c697a72f85941fd0db8ef1b28b86a 100644 (file)
@@ -1804,6 +1804,26 @@ void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata)
        mutex_unlock(&local->chanctx_mtx);
 }
 
+void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_chanctx_conf *chanctx_conf;
+       struct ieee80211_chanctx *chanctx;
+
+       mutex_lock(&local->chanctx_mtx);
+
+       chanctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
+                                       lockdep_is_held(&local->chanctx_mtx));
+
+       if (WARN_ON_ONCE(!chanctx_conf))
+               goto unlock;
+
+       chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
+       ieee80211_recalc_chanctx_min_def(local, chanctx);
+ unlock:
+       mutex_unlock(&local->chanctx_mtx);
+}
+
 static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id)
 {
        int i;
@@ -2259,14 +2279,17 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
 void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
 {
        struct ieee80211_sub_if_data *sdata;
+       struct cfg80211_chan_def chandef;
 
        mutex_lock(&local->iflist_mtx);
        list_for_each_entry(sdata, &local->interfaces, list) {
                cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
 
                if (sdata->wdev.cac_started) {
+                       chandef = sdata->vif.bss_conf.chandef;
                        ieee80211_vif_release_channel(sdata);
                        cfg80211_cac_event(sdata->dev,
+                                          &chandef,
                                           NL80211_RADAR_CAC_ABORTED,
                                           GFP_KERNEL);
                }
@@ -2445,7 +2468,6 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
 
        if (ieee80211_vif_is_mesh(&sdata->vif)) {
                struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-               __le16 pre_value;
 
                skb_put(skb, 8);
                *pos++ = WLAN_EID_CHAN_SWITCH_PARAM;            /* EID */
@@ -2457,11 +2479,78 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
                          WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
                put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */
                pos += 2;
-               pre_value = cpu_to_le16(ifmsh->pre_value);
-               memcpy(pos, &pre_value, 2);             /* Precedence Value */
+               put_unaligned_le16(ifmsh->pre_value, pos);/* Precedence Value */
                pos += 2;
        }
 
        ieee80211_tx_skb(sdata, skb);
        return 0;
 }
+
+bool ieee80211_cs_valid(const struct ieee80211_cipher_scheme *cs)
+{
+       return !(cs == NULL || cs->cipher == 0 ||
+                cs->hdr_len < cs->pn_len + cs->pn_off ||
+                cs->hdr_len <= cs->key_idx_off ||
+                cs->key_idx_shift > 7 ||
+                cs->key_idx_mask == 0);
+}
+
+bool ieee80211_cs_list_valid(const struct ieee80211_cipher_scheme *cs, int n)
+{
+       int i;
+
+       /* Ensure we have enough iftype bitmap space for all iftype values */
+       WARN_ON((NUM_NL80211_IFTYPES / 8 + 1) > sizeof(cs[0].iftype));
+
+       for (i = 0; i < n; i++)
+               if (!ieee80211_cs_valid(&cs[i]))
+                       return false;
+
+       return true;
+}
+
+const struct ieee80211_cipher_scheme *
+ieee80211_cs_get(struct ieee80211_local *local, u32 cipher,
+                enum nl80211_iftype iftype)
+{
+       const struct ieee80211_cipher_scheme *l = local->hw.cipher_schemes;
+       int n = local->hw.n_cipher_schemes;
+       int i;
+       const struct ieee80211_cipher_scheme *cs = NULL;
+
+       for (i = 0; i < n; i++) {
+               if (l[i].cipher == cipher) {
+                       cs = &l[i];
+                       break;
+               }
+       }
+
+       if (!cs || !(cs->iftype & BIT(iftype)))
+               return NULL;
+
+       return cs;
+}
+
+int ieee80211_cs_headroom(struct ieee80211_local *local,
+                         struct cfg80211_crypto_settings *crypto,
+                         enum nl80211_iftype iftype)
+{
+       const struct ieee80211_cipher_scheme *cs;
+       int headroom = IEEE80211_ENCRYPT_HEADROOM;
+       int i;
+
+       for (i = 0; i < crypto->n_ciphers_pairwise; i++) {
+               cs = ieee80211_cs_get(local, crypto->ciphers_pairwise[i],
+                                     iftype);
+
+               if (cs && headroom < cs->hdr_len)
+                       headroom = cs->hdr_len;
+       }
+
+       cs = ieee80211_cs_get(local, crypto->cipher_group, iftype);
+       if (cs && headroom < cs->hdr_len)
+               headroom = cs->hdr_len;
+
+       return headroom;
+}
index de0112785aae19a8b23b2f8f84b364c80d27e8b3..d75f35c6e1a0884eb9452030cb27bcafb33deeab 100644 (file)
@@ -182,16 +182,15 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
                         IEEE80211_VHT_CAP_SHORT_GI_160);
 
        /* remaining ones */
-       if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) {
+       if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
                vht_cap->cap |= cap_info &
                                (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
-                                IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX);
-       }
+                                IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK);
 
        if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
                vht_cap->cap |= cap_info &
                                (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
-                                IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX);
+                                IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK);
 
        if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
                vht_cap->cap |= cap_info &
index d6572822076367cdf203207892a2880c7e4487c2..7313d379c0d32aea2c6a152c9756263ff7bf523f 100644 (file)
@@ -545,6 +545,106 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
        return RX_CONTINUE;
 }
 
+static ieee80211_tx_result
+ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
+                           struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_key *key = tx->key;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       const struct ieee80211_cipher_scheme *cs = key->sta->cipher_scheme;
+       int hdrlen;
+       u8 *pos;
+
+       if (info->control.hw_key &&
+           !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
+               /* hwaccel has no need for preallocated head room */
+               return TX_CONTINUE;
+       }
+
+       if (unlikely(skb_headroom(skb) < cs->hdr_len &&
+                    pskb_expand_head(skb, cs->hdr_len, 0, GFP_ATOMIC)))
+               return TX_DROP;
+
+       hdrlen = ieee80211_hdrlen(hdr->frame_control);
+
+       pos = skb_push(skb, cs->hdr_len);
+       memmove(pos, pos + cs->hdr_len, hdrlen);
+       skb_set_network_header(skb, skb_network_offset(skb) + cs->hdr_len);
+
+       return TX_CONTINUE;
+}
+
+static inline int ieee80211_crypto_cs_pn_compare(u8 *pn1, u8 *pn2, int len)
+{
+       int i;
+
+       /* pn is little endian */
+       for (i = len - 1; i >= 0; i--) {
+               if (pn1[i] < pn2[i])
+                       return -1;
+               else if (pn1[i] > pn2[i])
+                       return 1;
+       }
+
+       return 0;
+}
+
+static ieee80211_rx_result
+ieee80211_crypto_cs_decrypt(struct ieee80211_rx_data *rx)
+{
+       struct ieee80211_key *key = rx->key;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
+       const struct ieee80211_cipher_scheme *cs = NULL;
+       int hdrlen = ieee80211_hdrlen(hdr->frame_control);
+       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+       int data_len;
+       u8 *rx_pn;
+       u8 *skb_pn;
+       u8 qos_tid;
+
+       if (!rx->sta || !rx->sta->cipher_scheme ||
+           !(status->flag & RX_FLAG_DECRYPTED))
+               return RX_DROP_UNUSABLE;
+
+       if (!ieee80211_is_data(hdr->frame_control))
+               return RX_CONTINUE;
+
+       cs = rx->sta->cipher_scheme;
+
+       data_len = rx->skb->len - hdrlen - cs->hdr_len;
+
+       if (data_len < 0)
+               return RX_DROP_UNUSABLE;
+
+       if (ieee80211_is_data_qos(hdr->frame_control))
+               qos_tid = *ieee80211_get_qos_ctl(hdr) &
+                               IEEE80211_QOS_CTL_TID_MASK;
+       else
+               qos_tid = 0;
+
+       if (skb_linearize(rx->skb))
+               return RX_DROP_UNUSABLE;
+
+       hdr = (struct ieee80211_hdr *)rx->skb->data;
+
+       rx_pn = key->u.gen.rx_pn[qos_tid];
+       skb_pn = rx->skb->data + hdrlen + cs->pn_off;
+
+       if (ieee80211_crypto_cs_pn_compare(skb_pn, rx_pn, cs->pn_len) <= 0)
+               return RX_DROP_UNUSABLE;
+
+       memcpy(rx_pn, skb_pn, cs->pn_len);
+
+       /* remove security header and MIC */
+       if (pskb_trim(rx->skb, rx->skb->len - cs->mic_len))
+               return RX_DROP_UNUSABLE;
+
+       memmove(rx->skb->data + cs->hdr_len, rx->skb->data, hdrlen);
+       skb_pull(rx->skb, cs->hdr_len);
+
+       return RX_CONTINUE;
+}
 
 static void bip_aad(struct sk_buff *skb, u8 *aad)
 {
@@ -685,6 +785,7 @@ ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx)
 {
        struct sk_buff *skb;
        struct ieee80211_tx_info *info = NULL;
+       ieee80211_tx_result res;
 
        skb_queue_walk(&tx->skbs, skb) {
                info  = IEEE80211_SKB_CB(skb);
@@ -692,9 +793,24 @@ ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx)
                /* handle hw-only algorithm */
                if (!info->control.hw_key)
                        return TX_DROP;
+
+               if (tx->key->sta->cipher_scheme) {
+                       res = ieee80211_crypto_cs_encrypt(tx, skb);
+                       if (res != TX_CONTINUE)
+                               return res;
+               }
        }
 
        ieee80211_tx_set_protected(tx);
 
        return TX_CONTINUE;
 }
+
+ieee80211_rx_result
+ieee80211_crypto_hw_decrypt(struct ieee80211_rx_data *rx)
+{
+       if (rx->sta->cipher_scheme)
+               return ieee80211_crypto_cs_decrypt(rx);
+
+       return RX_DROP_UNUSABLE;
+}
index 07e33f899c71fc52f9ff1771cd283226a8a64084..62e5a12dfe0a24010b32eec210d7a38a1c4c3eb8 100644 (file)
@@ -34,5 +34,7 @@ ieee80211_rx_result
 ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx);
 ieee80211_tx_result
 ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx);
+ieee80211_rx_result
+ieee80211_crypto_hw_decrypt(struct ieee80211_rx_data *rx);
 
 #endif /* WPA_H */
index c8beafd401aa283f0befa0494e02649359bab83f..d5f41514f5778d23293f6b9e36fe1bd9b83276e0 100644 (file)
@@ -19,8 +19,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  *
  * Authors:
index 7278145e6a68385c71b1d64efccc3aee71cb2412..69f78e96fdb44a5c293a92e53a98559b1ddf2209 100644 (file)
@@ -17,8 +17,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/module.h>
index 647d989a01e6b740f2d6c5b3d4f463259cecf643..7174611bd67294179e3456c06ab4c7155e71a77a 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
index 6f1701322fb695207684abc400452bb8e749c57a..d0a3acfa5742a295b63a875b970075447eb19cf4 100644 (file)
@@ -24,8 +24,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index a1287ce181300cef285ec6748d641c946453c1a2..d0f38bc9af6d8f485f3abe5cf5b923359d314ac1 100644 (file)
@@ -24,8 +24,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 69345cebe3a3e397beffbe56536bf971fb81ddf9..c2f2a53a487919bcb45e882b9ff8859c699b9d56 100644 (file)
@@ -23,8 +23,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index d24d774bfd62c065a5be92fb4e5e97cbb275e3ce..875826808b00bfa790a26a6abb70f0bf17278d46 100644 (file)
@@ -23,8 +23,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 85d842e6e43187998232441f5e2228244cb1cb95..f0cb92f3ddafa47063f82d54232e27308ea539fa 100644 (file)
@@ -24,8 +24,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index b9be0eed89801ab194b8f6a97899e7bbf9c50ec3..680caf4dff567f61ccaa41a70a9276101ac27fcd 100644 (file)
@@ -24,8 +24,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index dce1bebf7aecb98f4cfae0beb45a9b3c576c21d3..3045a964f39c82152574ef4479e01a0254c88f5a 100644 (file)
@@ -23,8 +23,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 8ef83ee97c6ad0fa934bbbe3d4988003e9ee287b..e66e977ef2fa0cf3ec52bc2ea3d6604d17de3e47 100644 (file)
@@ -23,8 +23,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 5a9f31ce5799baef8b6e83c4d56222cff7603d2b..8b6e1ab62b485729dca126c8ab6a82671623d1fe 100644 (file)
@@ -23,8 +23,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 43817d73ccf997b69ec15da814e274404e08a2c7..78a63c18779e443be49b5a9509499ab7cb43869a 100644 (file)
@@ -23,8 +23,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 700af49022a040a2d11a23747e51e1a0b6b9eca4..3a9e5dc9511b4a83564f6e99a9b7ef947aca0ea4 100644 (file)
@@ -23,8 +23,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 9650c4ad5f886ea29a7a02c82fffa100284ea5d7..1e779bb7fa435a7096342a1360b696b4a09a60cf 100644 (file)
@@ -23,8 +23,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index 81969785e279e6b47c5f50f391ed8bd371ad04e3..4a397cde1a48e4f296332bc8405d78a0ee612a25 100644 (file)
@@ -23,8 +23,7 @@
  * the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program;  if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
index ba2548bd85bf7d42b26e25ae9a2626b729fc8be9..c235da940019a450965d6777f9b478af58dee3d2 100644 (file)
@@ -437,7 +437,8 @@ static void prb_shutdown_retire_blk_timer(struct packet_sock *po,
 {
        struct tpacket_kbdq_core *pkc;
 
-       pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc;
+       pkc = tx_ring ? GET_PBDQC_FROM_RB(&po->tx_ring) :
+                       GET_PBDQC_FROM_RB(&po->rx_ring);
 
        spin_lock_bh(&rb_queue->lock);
        pkc->delete_blk_timer = 1;
@@ -463,7 +464,8 @@ static void prb_setup_retire_blk_timer(struct packet_sock *po, int tx_ring)
        if (tx_ring)
                BUG();
 
-       pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc;
+       pkc = tx_ring ? GET_PBDQC_FROM_RB(&po->tx_ring) :
+                       GET_PBDQC_FROM_RB(&po->rx_ring);
        prb_init_blk_timer(po, pkc, prb_retire_rx_blk_timer_expired);
 }
 
@@ -521,7 +523,7 @@ static void init_prb_bdqc(struct packet_sock *po,
                        struct pgv *pg_vec,
                        union tpacket_req_u *req_u, int tx_ring)
 {
-       struct tpacket_kbdq_core *p1 = &rb->prb_bdqc;
+       struct tpacket_kbdq_core *p1 = GET_PBDQC_FROM_RB(rb);
        struct tpacket_block_desc *pbd;
 
        memset(p1, 0x0, sizeof(*p1));
@@ -585,7 +587,7 @@ static void _prb_refresh_rx_retire_blk_timer(struct tpacket_kbdq_core *pkc)
 static void prb_retire_rx_blk_timer_expired(unsigned long data)
 {
        struct packet_sock *po = (struct packet_sock *)data;
-       struct tpacket_kbdq_core *pkc = &po->rx_ring.prb_bdqc;
+       struct tpacket_kbdq_core *pkc = GET_PBDQC_FROM_RB(&po->rx_ring);
        unsigned int frozen;
        struct tpacket_block_desc *pbd;
 
index cb4221171f93f0c5b8fbb98f41b11241aa17d02a..9119b73527c998e71535d5e0139a7dd93f7bf287 100644 (file)
@@ -11,8 +11,7 @@
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: Alexander Duyck <alexander.h.duyck@intel.com>
  */
index 2a2b096d9a664b12a2fa7b4b9a91e4ff9b233f27..afb050a735fa5878a29e1da85d7c6b603851b623 100644 (file)
@@ -11,8 +11,7 @@
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: Alexander Duyck <alexander.h.duyck@intel.com>
  */
index 68a27f9796d2ece54bcb53b98a47e8f98645077b..66882a26713b358c5e7793cdfaffe2d35c848481 100644 (file)
@@ -22,9 +22,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 46b5977978a131b15c073f3b23ab49fa511e92bc..5c9f64c1c906fc4cecd154a843c90e1efe56858c 100644 (file)
@@ -16,9 +16,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 077bb070052bac32e551cef707b0a6d6e3f65511..871cdf9567e6bc9c13cb1077dc6866a67e6e4367 100644 (file)
@@ -21,9 +21,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index f2044fcb9dd113d4764877f08bde77146be5d1a3..5573e425b0c0cc9ecc257994f98127be7ee24c3e 100644 (file)
@@ -18,9 +18,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 3d9a9ff69c036e6f83d3b85470458647f413bf5c..dd73758516181cd3268a54ff8aa3177e4f680843 100644 (file)
@@ -19,9 +19,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index e89015d8935a160f3e0f3e571a976d1cd4823993..95d7b15dad2143dc6a74003125be719e72aeee24 100644 (file)
@@ -22,9 +22,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 09b8daac87c8039f2c5b33e04b109a44e6006038..6ffb6c1b13b7efb1cb024c94f022eb1afacaf29a 100644 (file)
@@ -23,9 +23,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 98b69bbecdd96eadcbaeb3bdecc210dcca2ab11d..66038533ca5c572191666c045739ee7570ad4f53 100644 (file)
@@ -23,9 +23,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 5856932fdc38906ae78b3da2e170f0699634b24e..4de12afa13d42e75c62c4133fc089274e3000261 100644 (file)
@@ -24,9 +24,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 7567e6f1a9205bb0a37a29becc243d9ed6352fe4..32db816ffbaaeb769429898c48eae70c520ff865 100644 (file)
@@ -21,9 +21,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 647396baa56f3670de372a6896f2b36477c17a32..0c28e8a55324a69fd675dc1377187697d08cc365 100644 (file)
@@ -20,9 +20,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 0e2644d0a773710d149639ab3aa777c6313a7737..6371337e1fe71f934efbdf1465bcd5974ee59974 100644 (file)
@@ -20,9 +20,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index f51ba985a36eaaf0b021adba700cf16d42394e6f..b6b09f3f1a81f8f9fc6837cd79bb9749f6857cca 100644 (file)
@@ -22,9 +22,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index ce1ffd811775b414b4d79f3a7b55a5145d599bc9..ab8d9f96a177da9d900e01568cafc56b6b4cf1cb 100644 (file)
@@ -23,9 +23,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 0c06421568427e4995ea0798c9ca8535ca5ff9b5..de32e14f73980e9e498eca8667942db1e49f7793 100644 (file)
@@ -16,9 +16,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 5e17092f4adacbf0335dc33bcbde5a1f830b43df..19bd4c5bdae9c55658ed1a99758691a6948a13f6 100644 (file)
@@ -23,9 +23,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index fe690320b1e430a7915e35d36d26a72847368438..d9aaf9641aaa37ee234fb2be6c7339fc1f4eaca1 100644 (file)
@@ -23,9 +23,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 1a6eef39ab2fcd169dde99a6494758793f5c88fc..02b7ad1ff467cef05301f8f6818f1e5bba91b0e7 100644 (file)
@@ -22,9 +22,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index dfe3f36ff2aa27165b35a39d382583759cd3ebae..dd0eba919a8bedd5bad01ba13691ee2f4c908e97 100644 (file)
@@ -22,9 +22,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index c5999b2dde7dfa5fcd53e68cf3d7791e838e602b..a4f17437fb220ca9c1ac50fd89dffd25a644c091 100644 (file)
@@ -22,9 +22,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 72046b9729a8a6a669fb9c75446de8ef2fe345c6..191cd92578065bbee47b95d8200b81685012fb40 100644 (file)
@@ -28,9 +28,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 6007124aefa018fd958b9481e012f3db2df5a5da..b9c8521c1a984be0a34d991413a495282e47f83d 100644 (file)
@@ -18,9 +18,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 6b36561a1b3b7cceab5f5a4a9dce7aa2bc362266..80b17b5df6bb5079037ce0a6aa30ac3f450450c8 100644 (file)
@@ -19,9 +19,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index e332efb124cc0c34f93786232353c37dd2e10ea1..1d4f3ac29bafbf4b5a90c8648b87868501a8dd35 100644 (file)
@@ -24,9 +24,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index fbda20028285a8bb67c1052601a9986b90f50258..7635f9f2311d31d71297045cb93c2e4217f24b2d 100644 (file)
@@ -21,9 +21,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 81089ed654564db6367c27f174c9b8381557c512..85c64658bd0b183df5c7a7fd8394df757cb0b4b0 100644 (file)
@@ -22,9 +22,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 1c1484ed605d490686c8daa87e0a7e595b9fba3c..a67470083be8a42de0ce6a7c22a1ece650fa3290 100644 (file)
@@ -21,9 +21,8 @@
  * See the GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
index 9b8cc877eb191a2a62370c9f2617bed513200d24..78559b5bbd1fe1d98c533f18dd1cc4fce4087baa 100644 (file)
@@ -277,6 +277,32 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
                                     width, dfs_state);
 }
 
+static u32 cfg80211_get_start_freq(u32 center_freq,
+                                  u32 bandwidth)
+{
+       u32 start_freq;
+
+       if (bandwidth <= 20)
+               start_freq = center_freq;
+       else
+               start_freq = center_freq - bandwidth/2 + 10;
+
+       return start_freq;
+}
+
+static u32 cfg80211_get_end_freq(u32 center_freq,
+                                u32 bandwidth)
+{
+       u32 end_freq;
+
+       if (bandwidth <= 20)
+               end_freq = center_freq;
+       else
+               end_freq = center_freq + bandwidth/2 - 10;
+
+       return end_freq;
+}
+
 static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
                                            u32 center_freq,
                                            u32 bandwidth)
@@ -284,13 +310,8 @@ static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
        struct ieee80211_channel *c;
        u32 freq, start_freq, end_freq;
 
-       if (bandwidth <= 20) {
-               start_freq = center_freq;
-               end_freq = center_freq;
-       } else {
-               start_freq = center_freq - bandwidth/2 + 10;
-               end_freq = center_freq + bandwidth/2 - 10;
-       }
+       start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
+       end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
 
        for (freq = start_freq; freq <= end_freq; freq += 20) {
                c = ieee80211_get_channel(wiphy, freq);
@@ -330,33 +351,159 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
 }
 EXPORT_SYMBOL(cfg80211_chandef_dfs_required);
 
-static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
-                                       u32 center_freq, u32 bandwidth,
-                                       u32 prohibited_flags)
+static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy,
+                                        u32 center_freq,
+                                        u32 bandwidth)
 {
        struct ieee80211_channel *c;
        u32 freq, start_freq, end_freq;
+       int count = 0;
 
-       if (bandwidth <= 20) {
-               start_freq = center_freq;
-               end_freq = center_freq;
-       } else {
-               start_freq = center_freq - bandwidth/2 + 10;
-               end_freq = center_freq + bandwidth/2 - 10;
+       start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
+       end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
+
+       /*
+        * Check entire range of channels for the bandwidth.
+        * Check all channels are DFS channels (DFS_USABLE or
+        * DFS_AVAILABLE). Return number of usable channels
+        * (require CAC). Allow DFS and non-DFS channel mix.
+        */
+       for (freq = start_freq; freq <= end_freq; freq += 20) {
+               c = ieee80211_get_channel(wiphy, freq);
+               if (!c)
+                       return -EINVAL;
+
+               if (c->flags & IEEE80211_CHAN_DISABLED)
+                       return -EINVAL;
+
+               if (c->flags & IEEE80211_CHAN_RADAR) {
+                       if (c->dfs_state == NL80211_DFS_UNAVAILABLE)
+                               return -EINVAL;
+
+                       if (c->dfs_state == NL80211_DFS_USABLE)
+                               count++;
+               }
        }
 
+       return count;
+}
+
+bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
+                                const struct cfg80211_chan_def *chandef)
+{
+       int width;
+       int r1, r2 = 0;
+
+       if (WARN_ON(!cfg80211_chandef_valid(chandef)))
+               return false;
+
+       width = cfg80211_chandef_get_width(chandef);
+       if (width < 0)
+               return false;
+
+       r1 = cfg80211_get_chans_dfs_usable(wiphy, chandef->center_freq1,
+                                         width);
+
+       if (r1 < 0)
+               return false;
+
+       switch (chandef->width) {
+       case NL80211_CHAN_WIDTH_80P80:
+               WARN_ON(!chandef->center_freq2);
+               r2 = cfg80211_get_chans_dfs_usable(wiphy,
+                                                  chandef->center_freq2,
+                                                  width);
+               if (r2 < 0)
+                       return false;
+               break;
+       default:
+               WARN_ON(chandef->center_freq2);
+               break;
+       }
+
+       return (r1 + r2 > 0);
+}
+
+
+static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
+                                            u32 center_freq,
+                                            u32 bandwidth)
+{
+       struct ieee80211_channel *c;
+       u32 freq, start_freq, end_freq;
+
+       start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
+       end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
+
+       /*
+        * Check entire range of channels for the bandwidth.
+        * If any channel in between is disabled or has not
+        * had gone through CAC return false
+        */
        for (freq = start_freq; freq <= end_freq; freq += 20) {
                c = ieee80211_get_channel(wiphy, freq);
                if (!c)
                        return false;
 
-               /* check for radar flags */
-               if ((prohibited_flags & c->flags & IEEE80211_CHAN_RADAR) &&
+               if (c->flags & IEEE80211_CHAN_DISABLED)
+                       return false;
+
+               if ((c->flags & IEEE80211_CHAN_RADAR)  &&
                    (c->dfs_state != NL80211_DFS_AVAILABLE))
                        return false;
+       }
+
+       return true;
+}
+
+static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
+                               const struct cfg80211_chan_def *chandef)
+{
+       int width;
+       int r;
+
+       if (WARN_ON(!cfg80211_chandef_valid(chandef)))
+               return false;
+
+       width = cfg80211_chandef_get_width(chandef);
+       if (width < 0)
+               return false;
+
+       r = cfg80211_get_chans_dfs_available(wiphy, chandef->center_freq1,
+                                            width);
+
+       /* If any of channels unavailable for cf1 just return */
+       if (!r)
+               return r;
+
+       switch (chandef->width) {
+       case NL80211_CHAN_WIDTH_80P80:
+               WARN_ON(!chandef->center_freq2);
+               r = cfg80211_get_chans_dfs_available(wiphy,
+                                                    chandef->center_freq2,
+                                                    width);
+       default:
+               WARN_ON(chandef->center_freq2);
+               break;
+       }
+
+       return r;
+}
 
-               /* check for the other flags */
-               if (c->flags & prohibited_flags & ~IEEE80211_CHAN_RADAR)
+
+static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
+                                       u32 center_freq, u32 bandwidth,
+                                       u32 prohibited_flags)
+{
+       struct ieee80211_channel *c;
+       u32 freq, start_freq, end_freq;
+
+       start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
+       end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
+
+       for (freq = start_freq; freq <= end_freq; freq += 20) {
+               c = ieee80211_get_channel(wiphy, freq);
+               if (!c || c->flags & prohibited_flags)
                        return false;
        }
 
@@ -462,14 +609,19 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
                             struct cfg80211_chan_def *chandef)
 {
        bool res;
+       u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
+                              IEEE80211_CHAN_NO_IR |
+                              IEEE80211_CHAN_RADAR;
 
        trace_cfg80211_reg_can_beacon(wiphy, chandef);
 
-       res = cfg80211_chandef_usable(wiphy, chandef,
-                                     IEEE80211_CHAN_DISABLED |
-                                     IEEE80211_CHAN_PASSIVE_SCAN |
-                                     IEEE80211_CHAN_NO_IBSS |
-                                     IEEE80211_CHAN_RADAR);
+       if (cfg80211_chandef_dfs_required(wiphy, chandef) > 0 &&
+           cfg80211_chandef_dfs_available(wiphy, chandef)) {
+               /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */
+               prohibited_flags = IEEE80211_CHAN_DISABLED;
+       }
+
+       res = cfg80211_chandef_usable(wiphy, chandef, prohibited_flags);
 
        trace_cfg80211_return_bool(res);
        return res;
@@ -510,6 +662,7 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
                                  : CHAN_MODE_EXCLUSIVE;
                        return;
                }
+               break;
        case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_P2P_CLIENT:
                if (wdev->current_bss) {
index 52b865fb7351ac3c221c120bc0cc236687a12513..06db6eb5258aefc332fb4fb09ed165562ea8cd7d 100644 (file)
@@ -357,8 +357,6 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
        rdev->wiphy.rts_threshold = (u32) -1;
        rdev->wiphy.coverage_class = 0;
 
-       rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH;
-
        return &rdev->wiphy;
 }
 EXPORT_SYMBOL(wiphy_new);
@@ -575,6 +573,8 @@ int wiphy_register(struct wiphy *wiphy)
        /* check and set up bitrates */
        ieee80211_set_bitrate_flags(wiphy);
 
+       rdev->wiphy.features |= NL80211_FEATURE_SCAN_FLUSH;
+
        rtnl_lock();
        res = device_add(&rdev->wiphy.dev);
        if (res) {
@@ -595,7 +595,7 @@ int wiphy_register(struct wiphy *wiphy)
        if (IS_ERR(rdev->wiphy.debugfsdir))
                rdev->wiphy.debugfsdir = NULL;
 
-       if (wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
+       if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) {
                struct regulatory_request request;
 
                request.wiphy_idx = get_wiphy_idx(wiphy);
index af10e59af2d86f418bd7cc4e69914c9bb31831c7..0a277c33bb027a879d854492ddde295be2c663a0 100644 (file)
@@ -317,9 +317,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
                          struct wireless_dev *wdev,
-                         struct ieee80211_channel *chan, bool offchan,
-                         unsigned int wait, const u8 *buf, size_t len,
-                         bool no_cck, bool dont_wait_for_ack, u64 *cookie);
+                         struct cfg80211_mgmt_tx_params *params,
+                         u64 *cookie);
 void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
                               const struct ieee80211_ht_cap *ht_capa_mask);
 void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
@@ -382,6 +381,19 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
                                 enum cfg80211_chan_mode chanmode,
                                 u8 radar_detect);
 
+/**
+ * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable
+ * @wiphy: the wiphy to validate against
+ * @chandef: the channel definition to check
+ *
+ * Checks if chandef is usable and we can/need start CAC on such channel.
+ *
+ * Return: Return true if all channels available and at least
+ *        one channel require CAC (NL80211_DFS_USABLE)
+ */
+bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
+                                const struct cfg80211_chan_def *chandef);
+
 void cfg80211_set_dfs_state(struct wiphy *wiphy,
                            const struct cfg80211_chan_def *chandef,
                            enum nl80211_dfs_state dfs_state);
index 42ed274e81f4ca7debc59c4ae17137c35a0993d8..9a8217d2a90882f872451833cabe30159a64953f 100644 (file)
@@ -33,15 +33,7 @@ BEGIN {
        regdb = "const struct ieee80211_regdomain *reg_regdb[] = {\n"
 }
 
-/^[ \t]*#/ {
-       # Ignore
-}
-
-!active && /^[ \t]*$/ {
-       # Ignore
-}
-
-!active && /country/ {
+function parse_country_head() {
        country=$2
        sub(/:/, "", country)
        printf "static const struct ieee80211_regdomain regdom_%s = {\n", country
@@ -57,7 +49,8 @@ BEGIN {
        regdb = regdb "\t&regdom_" country ",\n"
 }
 
-active && /^[ \t]*\(/ {
+function parse_reg_rule()
+{
        start = $1
        sub(/\(/, "", start)
        end = $3
@@ -107,17 +100,21 @@ active && /^[ \t]*\(/ {
                } else if (flagarray[arg] == "PTMP-ONLY") {
                        flags = flags "\n\t\t\tNL80211_RRF_PTMP_ONLY | "
                } else if (flagarray[arg] == "PASSIVE-SCAN") {
-                       flags = flags "\n\t\t\tNL80211_RRF_PASSIVE_SCAN | "
+                       flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
                } else if (flagarray[arg] == "NO-IBSS") {
-                       flags = flags "\n\t\t\tNL80211_RRF_NO_IBSS | "
+                       flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
+               } else if (flagarray[arg] == "NO-IR") {
+                       flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
                }
+
        }
        flags = flags "0"
        printf "\t\tREG_RULE(%d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, flags
        rules++
 }
 
-active && /^[ \t]*$/ {
+function print_tail_country()
+{
        active = 0
        printf "\t},\n"
        printf "\t.n_reg_rules = %d\n", rules
@@ -125,7 +122,29 @@ active && /^[ \t]*$/ {
        rules = 0;
 }
 
+/^[ \t]*#/ {
+       # Ignore
+}
+
+!active && /^[ \t]*$/ {
+       # Ignore
+}
+
+!active && /country/ {
+       parse_country_head()
+}
+
+active && /^[ \t]*\(/ {
+       parse_reg_rule()
+}
+
+active && /^[ \t]*$/ {
+       print_tail_country()
+}
+
 END {
+       if (active)
+               print_tail_country()
        print regdb "};"
        print ""
        print "int reg_regdb_size = ARRAY_SIZE(reg_regdb);"
index 89737ee2669a8de9bc8f02aa1c392052369d210b..730147ed8e652c625cb035309df687ca08fd5b49 100644 (file)
@@ -274,7 +274,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
 
                        for (i = 0; i < sband->n_channels; i++) {
                                chan = &sband->channels[i];
-                               if (chan->flags & IEEE80211_CHAN_NO_IBSS)
+                               if (chan->flags & IEEE80211_CHAN_NO_IR)
                                        continue;
                                if (chan->flags & IEEE80211_CHAN_DISABLED)
                                        continue;
@@ -346,7 +346,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
                chan = ieee80211_get_channel(wdev->wiphy, freq);
                if (!chan)
                        return -EINVAL;
-               if (chan->flags & IEEE80211_CHAN_NO_IBSS ||
+               if (chan->flags & IEEE80211_CHAN_NO_IR ||
                    chan->flags & IEEE80211_CHAN_DISABLED)
                        return -EINVAL;
        }
index 0553fd4d85aeb4b9338d2661ba020448105a68e9..b0e1869de7de0b0775561c445389f4f2013beb58 100644 (file)
@@ -141,8 +141,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 
                        for (i = 0; i < sband->n_channels; i++) {
                                chan = &sband->channels[i];
-                               if (chan->flags & (IEEE80211_CHAN_NO_IBSS |
-                                                  IEEE80211_CHAN_PASSIVE_SCAN |
+                               if (chan->flags & (IEEE80211_CHAN_NO_IR |
                                                   IEEE80211_CHAN_DISABLED |
                                                   IEEE80211_CHAN_RADAR))
                                        continue;
index 6a6b1c8e907df93e73b44a8912a3ae1fda5f80a5..52cca05044a898b977927f2c9e540b00d6811634 100644 (file)
@@ -520,9 +520,7 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
 
 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
                          struct wireless_dev *wdev,
-                         struct ieee80211_channel *chan, bool offchan,
-                         unsigned int wait, const u8 *buf, size_t len,
-                         bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+                         struct cfg80211_mgmt_tx_params *params, u64 *cookie)
 {
        const struct ieee80211_mgmt *mgmt;
        u16 stype;
@@ -533,10 +531,10 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
        if (!rdev->ops->mgmt_tx)
                return -EOPNOTSUPP;
 
-       if (len < 24 + 1)
+       if (params->len < 24 + 1)
                return -EINVAL;
 
-       mgmt = (const struct ieee80211_mgmt *) buf;
+       mgmt = (const struct ieee80211_mgmt *)params->buf;
 
        if (!ieee80211_is_mgmt(mgmt->frame_control))
                return -EINVAL;
@@ -615,9 +613,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
                return -EINVAL;
 
        /* Transmit the Action frame as requested by user space */
-       return rdev_mgmt_tx(rdev, wdev, chan, offchan,
-                           wait, buf, len, no_cck, dont_wait_for_ack,
-                           cookie);
+       return rdev_mgmt_tx(rdev, wdev, params, cookie);
 }
 
 bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
@@ -763,12 +759,12 @@ void cfg80211_radar_event(struct wiphy *wiphy,
 EXPORT_SYMBOL(cfg80211_radar_event);
 
 void cfg80211_cac_event(struct net_device *netdev,
+                       const struct cfg80211_chan_def *chandef,
                        enum nl80211_radar_event event, gfp_t gfp)
 {
        struct wireless_dev *wdev = netdev->ieee80211_ptr;
        struct wiphy *wiphy = wdev->wiphy;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-       struct cfg80211_chan_def chandef;
        unsigned long timeout;
 
        trace_cfg80211_cac_event(netdev, event);
@@ -779,14 +775,12 @@ void cfg80211_cac_event(struct net_device *netdev,
        if (WARN_ON(!wdev->channel))
                return;
 
-       cfg80211_chandef_create(&chandef, wdev->channel, NL80211_CHAN_NO_HT);
-
        switch (event) {
        case NL80211_RADAR_CAC_FINISHED:
                timeout = wdev->cac_start_time +
                          msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
                WARN_ON(!time_after_eq(jiffies, timeout));
-               cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_AVAILABLE);
+               cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
                break;
        case NL80211_RADAR_CAC_ABORTED:
                break;
@@ -796,6 +790,6 @@ void cfg80211_cac_event(struct net_device *netdev,
        }
        wdev->cac_started = false;
 
-       nl80211_radar_notify(rdev, &chandef, event, netdev, gfp);
+       nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
 }
 EXPORT_SYMBOL(cfg80211_cac_event);
index 138dc3bb8b67d8c345531a95ce0c8342271ce79e..a693f86e59704016e9c8419eb82a8c43185d9642 100644 (file)
@@ -564,12 +564,12 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
        if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
            nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
                goto nla_put_failure;
-       if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
-           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN))
-               goto nla_put_failure;
-       if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
-           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS))
-               goto nla_put_failure;
+       if (chan->flags & IEEE80211_CHAN_NO_IR) {
+               if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
+                       goto nla_put_failure;
+               if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
+                       goto nla_put_failure;
+       }
        if (chan->flags & IEEE80211_CHAN_RADAR) {
                if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
                        goto nla_put_failure;
@@ -1247,10 +1247,6 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
                if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
                    nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
                        goto nla_put_failure;
-               if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
-                   nla_put_flag(msg, WIPHY_FLAG_SUPPORTS_5_10_MHZ))
-                       goto nla_put_failure;
-
                state->split_start++;
                if (state->split)
                        break;
@@ -1579,6 +1575,11 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
                if (nl80211_send_coalesce(msg, dev))
                        goto nla_put_failure;
 
+               if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
+                   (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
+                    nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
+                       goto nla_put_failure;
+
                /* done */
                state->split_start = 0;
                break;
@@ -2187,7 +2188,7 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
 }
 
 static int nl80211_send_chandef(struct sk_buff *msg,
-                                struct cfg80211_chan_def *chandef)
+                               const struct cfg80211_chan_def *chandef)
 {
        WARN_ON(!cfg80211_chandef_valid(chandef));
 
@@ -3236,6 +3237,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
                        return PTR_ERR(params.acl);
        }
 
+       wdev_lock(wdev);
        err = rdev_start_ap(rdev, dev, &params);
        if (!err) {
                wdev->preset_chandef = params.chandef;
@@ -3244,6 +3246,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
                wdev->ssid_len = params.ssid_len;
                memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
        }
+       wdev_unlock(wdev);
 
        kfree(params.acl);
 
@@ -3272,7 +3275,11 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
        if (err)
                return err;
 
-       return rdev_change_beacon(rdev, dev, &params);
+       wdev_lock(wdev);
+       err = rdev_change_beacon(rdev, dev, &params);
+       wdev_unlock(wdev);
+
+       return err;
 }
 
 static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
@@ -4478,7 +4485,9 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
        struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct bss_parameters params;
+       int err;
 
        memset(&params, 0, sizeof(params));
        /* default to not changing parameters */
@@ -4544,7 +4553,11 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
            dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
                return -EOPNOTSUPP;
 
-       return rdev_change_bss(rdev, dev, &params);
+       wdev_lock(wdev);
+       err = rdev_change_bss(rdev, dev, &params);
+       wdev_unlock(wdev);
+
+       return err;
 }
 
 static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
@@ -5098,7 +5111,7 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
        char *alpha2 = NULL;
        int rem_reg_rules = 0, r = 0;
        u32 num_rules = 0, rule_idx = 0, size_of_regd;
-       u8 dfs_region = 0;
+       enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
        struct ieee80211_regdomain *rd = NULL;
 
        if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
@@ -5119,6 +5132,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
                        return -EINVAL;
        }
 
+       if (!reg_is_valid_request(alpha2))
+               return -EINVAL;
+
        size_of_regd = sizeof(struct ieee80211_regdomain) +
                       num_rules * sizeof(struct ieee80211_reg_rule);
 
@@ -5365,10 +5381,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
                request->flags = nla_get_u32(
                        info->attrs[NL80211_ATTR_SCAN_FLAGS]);
-               if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
-                    !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
-                   ((request->flags & NL80211_SCAN_FLAG_FLUSH) &&
-                    !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) {
+               if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
+                   !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
                        err = -EOPNOTSUPP;
                        goto out_free;
                }
@@ -5608,10 +5622,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
        if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
                request->flags = nla_get_u32(
                        info->attrs[NL80211_ATTR_SCAN_FLAGS]);
-               if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
-                    !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
-                   ((request->flags & NL80211_SCAN_FLAG_FLUSH) &&
-                    !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) {
+               if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
+                   !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
                        err = -EOPNOTSUPP;
                        goto out_free;
                }
@@ -5674,7 +5686,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
        if (err == 0)
                return -EINVAL;
 
-       if (chandef.chan->dfs_state != NL80211_DFS_USABLE)
+       if (!cfg80211_chandef_dfs_usable(wdev->wiphy, &chandef))
                return -EINVAL;
 
        if (!rdev->ops->start_radar_detection)
@@ -5814,7 +5826,11 @@ skip_beacons:
        if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
                params.block_tx = true;
 
-       return rdev_channel_switch(rdev, dev, &params);
+       wdev_lock(wdev);
+       err = rdev_channel_switch(rdev, dev, &params);
+       wdev_unlock(wdev);
+
+       return err;
 }
 
 static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
@@ -7447,10 +7463,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
        void *hdr = NULL;
        u64 cookie;
        struct sk_buff *msg = NULL;
-       unsigned int wait = 0;
-       bool offchan, no_cck, dont_wait_for_ack;
-
-       dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
+       struct cfg80211_mgmt_tx_params params = {
+               .dont_wait_for_ack =
+                       info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
+       };
 
        if (!info->attrs[NL80211_ATTR_FRAME])
                return -EINVAL;
@@ -7477,24 +7493,24 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
        if (info->attrs[NL80211_ATTR_DURATION]) {
                if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
                        return -EINVAL;
-               wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
+               params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
 
                /*
                 * We should wait on the channel for at least a minimum amount
                 * of time (10ms) but no longer than the driver supports.
                 */
-               if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
-                   wait > rdev->wiphy.max_remain_on_channel_duration)
+               if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
+                   params.wait > rdev->wiphy.max_remain_on_channel_duration)
                        return -EINVAL;
 
        }
 
-       offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
+       params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
 
-       if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
+       if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
                return -EINVAL;
 
-       no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
+       params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
 
        /* get the channel if any has been specified, otherwise pass NULL to
         * the driver. The latter will use the current one
@@ -7506,10 +7522,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
                        return err;
        }
 
-       if (!chandef.chan && offchan)
+       if (!chandef.chan && params.offchan)
                return -EINVAL;
 
-       if (!dont_wait_for_ack) {
+       if (!params.dont_wait_for_ack) {
                msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
                if (!msg)
                        return -ENOMEM;
@@ -7522,10 +7538,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
                }
        }
 
-       err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait,
-                                   nla_data(info->attrs[NL80211_ATTR_FRAME]),
-                                   nla_len(info->attrs[NL80211_ATTR_FRAME]),
-                                   no_cck, dont_wait_for_ack, &cookie);
+       params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
+       params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
+       params.chan = chandef.chan;
+       err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
        if (err)
                goto free_msg;
 
@@ -10810,21 +10826,18 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
        struct wiphy *wiphy = wdev->wiphy;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
-       trace_cfg80211_ch_switch_notify(dev, chandef);
+       ASSERT_WDEV_LOCK(wdev);
 
-       wdev_lock(wdev);
+       trace_cfg80211_ch_switch_notify(dev, chandef);
 
        if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
                    wdev->iftype != NL80211_IFTYPE_P2P_GO &&
                    wdev->iftype != NL80211_IFTYPE_ADHOC &&
                    wdev->iftype != NL80211_IFTYPE_MESH_POINT))
-               goto out;
+               return;
 
        wdev->channel = chandef->chan;
        nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
-out:
-       wdev_unlock(wdev);
-       return;
 }
 EXPORT_SYMBOL(cfg80211_ch_switch_notify);
 
@@ -10883,7 +10896,7 @@ EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
 
 void
 nl80211_radar_notify(struct cfg80211_registered_device *rdev,
-                    struct cfg80211_chan_def *chandef,
+                    const struct cfg80211_chan_def *chandef,
                     enum nl80211_radar_event event,
                     struct net_device *netdev, gfp_t gfp)
 {
index 2c0f2b3c07cba7e4c2f50b17895d498c79d08dfb..b1b231324e102a44218bcf2354e52662fac78f5a 100644 (file)
@@ -70,7 +70,7 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
 
 void
 nl80211_radar_notify(struct cfg80211_registered_device *rdev,
-                    struct cfg80211_chan_def *chandef,
+                    const struct cfg80211_chan_def *chandef,
                     enum nl80211_radar_event event,
                     struct net_device *netdev, gfp_t gfp);
 
index 37ce9fdfe934345fe6603b399b8c4d3fd4f44ec1..a6c03ab14a0d47ea9a7f676dec76301804ab809b 100644 (file)
@@ -624,16 +624,12 @@ rdev_cancel_remain_on_channel(struct cfg80211_registered_device *rdev,
 
 static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev,
                               struct wireless_dev *wdev,
-                              struct ieee80211_channel *chan, bool offchan,
-                              unsigned int wait, const u8 *buf, size_t len,
-                              bool no_cck, bool dont_wait_for_ack, u64 *cookie)
+                              struct cfg80211_mgmt_tx_params *params,
+                              u64 *cookie)
 {
        int ret;
-       trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
-                          wait, no_cck, dont_wait_for_ack);
-       ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
-                                 wait, buf, len, no_cck,
-                                 dont_wait_for_ack, cookie);
+       trace_rdev_mgmt_tx(&rdev->wiphy, wdev, params);
+       ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, params, cookie);
        trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
        return ret;
 }
index 7da67fd0b4188a7cf3e3ded0ae2a64d565274947..ec54e1aac8e29c01e89ab4d0c6e9078bf112b5f9 100644 (file)
@@ -120,6 +120,21 @@ static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
        return rtnl_dereference(wiphy->regd);
 }
 
+static const char *reg_dfs_region_str(enum nl80211_dfs_regions dfs_region)
+{
+       switch (dfs_region) {
+       case NL80211_DFS_UNSET:
+               return "unset";
+       case NL80211_DFS_FCC:
+               return "FCC";
+       case NL80211_DFS_ETSI:
+               return "ETSI";
+       case NL80211_DFS_JP:
+               return "JP";
+       }
+       return "Unknown";
+}
+
 static void rcu_free_regdom(const struct ieee80211_regdomain *r)
 {
        if (!r)
@@ -163,35 +178,29 @@ static const struct ieee80211_regdomain world_regdom = {
                REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
                /* IEEE 802.11b/g, channels 12..13. */
                REG_RULE(2467-10, 2472+10, 40, 6, 20,
-                       NL80211_RRF_PASSIVE_SCAN |
-                       NL80211_RRF_NO_IBSS),
+                       NL80211_RRF_NO_IR),
                /* IEEE 802.11 channel 14 - Only JP enables
                 * this and for 802.11b only */
                REG_RULE(2484-10, 2484+10, 20, 6, 20,
-                       NL80211_RRF_PASSIVE_SCAN |
-                       NL80211_RRF_NO_IBSS |
+                       NL80211_RRF_NO_IR |
                        NL80211_RRF_NO_OFDM),
                /* IEEE 802.11a, channel 36..48 */
                REG_RULE(5180-10, 5240+10, 160, 6, 20,
-                        NL80211_RRF_PASSIVE_SCAN |
-                        NL80211_RRF_NO_IBSS),
+                        NL80211_RRF_NO_IR),
 
                /* IEEE 802.11a, channel 52..64 - DFS required */
                REG_RULE(5260-10, 5320+10, 160, 6, 20,
-                       NL80211_RRF_PASSIVE_SCAN |
-                       NL80211_RRF_NO_IBSS |
+                       NL80211_RRF_NO_IR |
                        NL80211_RRF_DFS),
 
                /* IEEE 802.11a, channel 100..144 - DFS required */
                REG_RULE(5500-10, 5720+10, 160, 6, 20,
-                       NL80211_RRF_PASSIVE_SCAN |
-                       NL80211_RRF_NO_IBSS |
+                       NL80211_RRF_NO_IR |
                        NL80211_RRF_DFS),
 
                /* IEEE 802.11a, channel 149..165 */
                REG_RULE(5745-10, 5825+10, 80, 6, 20,
-                       NL80211_RRF_PASSIVE_SCAN |
-                       NL80211_RRF_NO_IBSS),
+                       NL80211_RRF_NO_IR),
 
                /* IEEE 802.11ad (60gHz), channels 1..3 */
                REG_RULE(56160+2160*1-1080, 56160+2160*3+1080, 2160, 0, 0, 0),
@@ -208,11 +217,26 @@ static char user_alpha2[2];
 module_param(ieee80211_regdom, charp, 0444);
 MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
 
+static void reg_kfree_last_request(void)
+{
+       struct regulatory_request *lr;
+
+       lr = get_last_request();
+
+       if (lr != &core_request_world && lr)
+               kfree_rcu(lr, rcu_head);
+}
+
+static void reg_update_last_request(struct regulatory_request *request)
+{
+       reg_kfree_last_request();
+       rcu_assign_pointer(last_request, request);
+}
+
 static void reset_regdomains(bool full_reset,
                             const struct ieee80211_regdomain *new_regdom)
 {
        const struct ieee80211_regdomain *r;
-       struct regulatory_request *lr;
 
        ASSERT_RTNL();
 
@@ -235,10 +259,7 @@ static void reset_regdomains(bool full_reset,
        if (!full_reset)
                return;
 
-       lr = get_last_request();
-       if (lr != &core_request_world && lr)
-               kfree_rcu(lr, rcu_head);
-       rcu_assign_pointer(last_request, &core_request_world);
+       reg_update_last_request(&core_request_world);
 }
 
 /*
@@ -456,7 +477,15 @@ static int call_crda(const char *alpha2)
        return kobject_uevent(&reg_pdev->dev.kobj, KOBJ_CHANGE);
 }
 
-static bool reg_is_valid_request(const char *alpha2)
+static enum reg_request_treatment
+reg_call_crda(struct regulatory_request *request)
+{
+       if (call_crda(request->alpha2))
+               return REG_REQ_IGNORE;
+       return REG_REQ_OK;
+}
+
+bool reg_is_valid_request(const char *alpha2)
 {
        struct regulatory_request *lr = get_last_request();
 
@@ -556,6 +585,20 @@ static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
 #undef ONE_GHZ_IN_KHZ
 }
 
+/*
+ * Later on we can perhaps use the more restrictive DFS
+ * region but we don't have information for that yet so
+ * for now simply disallow conflicts.
+ */
+static enum nl80211_dfs_regions
+reg_intersect_dfs_region(const enum nl80211_dfs_regions dfs_region1,
+                        const enum nl80211_dfs_regions dfs_region2)
+{
+       if (dfs_region1 != dfs_region2)
+               return NL80211_DFS_UNSET;
+       return dfs_region1;
+}
+
 /*
  * Helper for regdom_intersect(), this does the real
  * mathematical intersection fun
@@ -687,6 +730,8 @@ regdom_intersect(const struct ieee80211_regdomain *rd1,
        rd->n_reg_rules = num_rules;
        rd->alpha2[0] = '9';
        rd->alpha2[1] = '8';
+       rd->dfs_region = reg_intersect_dfs_region(rd1->dfs_region,
+                                                 rd2->dfs_region);
 
        return rd;
 }
@@ -698,10 +743,8 @@ regdom_intersect(const struct ieee80211_regdomain *rd1,
 static u32 map_regdom_flags(u32 rd_flags)
 {
        u32 channel_flags = 0;
-       if (rd_flags & NL80211_RRF_PASSIVE_SCAN)
-               channel_flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-       if (rd_flags & NL80211_RRF_NO_IBSS)
-               channel_flags |= IEEE80211_CHAN_NO_IBSS;
+       if (rd_flags & NL80211_RRF_NO_IR_ALL)
+               channel_flags |= IEEE80211_CHAN_NO_IR;
        if (rd_flags & NL80211_RRF_DFS)
                channel_flags |= IEEE80211_CHAN_RADAR;
        if (rd_flags & NL80211_RRF_NO_OFDM)
@@ -854,8 +897,18 @@ static void handle_channel(struct wiphy *wiphy,
                    PTR_ERR(reg_rule) == -ERANGE)
                        return;
 
-               REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq);
-               chan->flags |= IEEE80211_CHAN_DISABLED;
+               if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
+                   request_wiphy && request_wiphy == wiphy &&
+                   request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) {
+                       REG_DBG_PRINT("Disabling freq %d MHz for good\n",
+                                     chan->center_freq);
+                       chan->orig_flags |= IEEE80211_CHAN_DISABLED;
+                       chan->flags = chan->orig_flags;
+               } else {
+                       REG_DBG_PRINT("Disabling freq %d MHz\n",
+                                     chan->center_freq);
+                       chan->flags |= IEEE80211_CHAN_DISABLED;
+               }
                return;
        }
 
@@ -873,7 +926,7 @@ static void handle_channel(struct wiphy *wiphy,
 
        if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
            request_wiphy && request_wiphy == wiphy &&
-           request_wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) {
+           request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) {
                /*
                 * This guarantees the driver's requested regulatory domain
                 * will always be used as a base for further regulatory
@@ -899,13 +952,11 @@ static void handle_channel(struct wiphy *wiphy,
        chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
        if (chan->orig_mpwr) {
                /*
-                * Devices that have their own custom regulatory domain
-                * but also use WIPHY_FLAG_STRICT_REGULATORY will follow the
-                * passed country IE power settings.
+                * Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER
+                * will always follow the passed country IE power settings.
                 */
                if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
-                   wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY &&
-                   wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
+                   wiphy->regulatory_flags & REGULATORY_COUNTRY_IE_FOLLOW_POWER)
                        chan->max_power = chan->max_reg_power;
                else
                        chan->max_power = min(chan->orig_mpwr,
@@ -975,8 +1026,8 @@ static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy)
 
 static bool wiphy_strict_alpha2_regd(struct wiphy *wiphy)
 {
-       if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY &&
-           !(wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY))
+       if (wiphy->regulatory_flags & REGULATORY_STRICT_REG &&
+           !(wiphy->regulatory_flags & REGULATORY_CUSTOM_REG))
                return true;
        return false;
 }
@@ -994,7 +1045,7 @@ static bool ignore_reg_update(struct wiphy *wiphy,
        }
 
        if (initiator == NL80211_REGDOM_SET_BY_CORE &&
-           wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
+           wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) {
                REG_DBG_PRINT("Ignoring regulatory request set by %s "
                              "since the driver uses its own custom "
                              "regulatory domain\n",
@@ -1032,7 +1083,7 @@ static bool reg_is_world_roaming(struct wiphy *wiphy)
                return true;
 
        if (lr && lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
-           wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)
+           wiphy->regulatory_flags & REGULATORY_CUSTOM_REG)
                return true;
 
        return false;
@@ -1060,19 +1111,14 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx,
        if (!reg_is_world_roaming(wiphy))
                return;
 
-       if (wiphy->flags & WIPHY_FLAG_DISABLE_BEACON_HINTS)
+       if (wiphy->regulatory_flags & REGULATORY_DISABLE_BEACON_HINTS)
                return;
 
        chan_before.center_freq = chan->center_freq;
        chan_before.flags = chan->flags;
 
-       if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
-               chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-               channel_changed = true;
-       }
-
-       if (chan->flags & IEEE80211_CHAN_NO_IBSS) {
-               chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
+       if (chan->flags & IEEE80211_CHAN_NO_IR) {
+               chan->flags &= ~IEEE80211_CHAN_NO_IR;
                channel_changed = true;
        }
 
@@ -1205,14 +1251,30 @@ static void reg_process_ht_flags(struct wiphy *wiphy)
                reg_process_ht_flags_band(wiphy, wiphy->bands[band]);
 }
 
+static void reg_call_notifier(struct wiphy *wiphy,
+                             struct regulatory_request *request)
+{
+       if (wiphy->reg_notifier)
+               wiphy->reg_notifier(wiphy, request);
+}
+
 static void wiphy_update_regulatory(struct wiphy *wiphy,
                                    enum nl80211_reg_initiator initiator)
 {
        enum ieee80211_band band;
        struct regulatory_request *lr = get_last_request();
 
-       if (ignore_reg_update(wiphy, initiator))
+       if (ignore_reg_update(wiphy, initiator)) {
+               /*
+                * Regulatory updates set by CORE are ignored for custom
+                * regulatory cards. Let us notify the changes to the driver,
+                * as some drivers used this to restore its orig_* reg domain.
+                */
+               if (initiator == NL80211_REGDOM_SET_BY_CORE &&
+                   wiphy->regulatory_flags & REGULATORY_CUSTOM_REG)
+                       reg_call_notifier(wiphy, lr);
                return;
+       }
 
        lr->dfs_region = get_cfg80211_regdom()->dfs_region;
 
@@ -1221,9 +1283,7 @@ static void wiphy_update_regulatory(struct wiphy *wiphy,
 
        reg_process_beacons(wiphy);
        reg_process_ht_flags(wiphy);
-
-       if (wiphy->reg_notifier)
-               wiphy->reg_notifier(wiphy, lr);
+       reg_call_notifier(wiphy, lr);
 }
 
 static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
@@ -1236,15 +1296,6 @@ static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
        list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
                wiphy = &rdev->wiphy;
                wiphy_update_regulatory(wiphy, initiator);
-               /*
-                * Regulatory updates set by CORE are ignored for custom
-                * regulatory cards. Let us notify the changes to the driver,
-                * as some drivers used this to restore its orig_* reg domain.
-                */
-               if (initiator == NL80211_REGDOM_SET_BY_CORE &&
-                   wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY &&
-                   wiphy->reg_notifier)
-                       wiphy->reg_notifier(wiphy, get_last_request());
        }
 }
 
@@ -1263,7 +1314,8 @@ static void handle_channel_custom(struct wiphy *wiphy,
        if (IS_ERR(reg_rule)) {
                REG_DBG_PRINT("Disabling freq %d MHz as custom regd has no rule that fits it\n",
                              chan->center_freq);
-               chan->flags = IEEE80211_CHAN_DISABLED;
+               chan->orig_flags |= IEEE80211_CHAN_DISABLED;
+               chan->flags = chan->orig_flags;
                return;
        }
 
@@ -1305,6 +1357,10 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
        enum ieee80211_band band;
        unsigned int bands_set = 0;
 
+       WARN(!(wiphy->regulatory_flags & REGULATORY_CUSTOM_REG),
+            "wiphy should have REGULATORY_CUSTOM_REG\n");
+       wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
+
        for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
                if (!wiphy->bands[band])
                        continue;
@@ -1320,225 +1376,285 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
 }
 EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
 
-/* This has the logic which determines when a new request
- * should be ignored. */
-static enum reg_request_treatment
-get_reg_request_treatment(struct wiphy *wiphy,
-                         struct regulatory_request *pending_request)
+static void reg_set_request_processed(void)
 {
-       struct wiphy *last_wiphy = NULL;
+       bool need_more_processing = false;
        struct regulatory_request *lr = get_last_request();
 
-       /* All initial requests are respected */
-       if (!lr)
-               return REG_REQ_OK;
+       lr->processed = true;
 
-       switch (pending_request->initiator) {
-       case NL80211_REGDOM_SET_BY_CORE:
-               return REG_REQ_OK;
-       case NL80211_REGDOM_SET_BY_COUNTRY_IE:
-               if (reg_request_cell_base(lr)) {
-                       /* Trust a Cell base station over the AP's country IE */
-                       if (regdom_changes(pending_request->alpha2))
-                               return REG_REQ_IGNORE;
-                       return REG_REQ_ALREADY_SET;
-               }
+       spin_lock(&reg_requests_lock);
+       if (!list_empty(&reg_requests_list))
+               need_more_processing = true;
+       spin_unlock(&reg_requests_lock);
 
-               last_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx);
+       if (lr->initiator == NL80211_REGDOM_SET_BY_USER)
+               cancel_delayed_work(&reg_timeout);
 
-               if (unlikely(!is_an_alpha2(pending_request->alpha2)))
-                       return -EINVAL;
-               if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
-                       if (last_wiphy != wiphy) {
-                               /*
-                                * Two cards with two APs claiming different
-                                * Country IE alpha2s. We could
-                                * intersect them, but that seems unlikely
-                                * to be correct. Reject second one for now.
-                                */
-                               if (regdom_changes(pending_request->alpha2))
-                                       return REG_REQ_IGNORE;
-                               return REG_REQ_ALREADY_SET;
-                       }
-                       /*
-                        * Two consecutive Country IE hints on the same wiphy.
-                        * This should be picked up early by the driver/stack
-                        */
-                       if (WARN_ON(regdom_changes(pending_request->alpha2)))
-                               return REG_REQ_OK;
-                       return REG_REQ_ALREADY_SET;
-               }
-               return REG_REQ_OK;
-       case NL80211_REGDOM_SET_BY_DRIVER:
-               if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) {
-                       if (regdom_changes(pending_request->alpha2))
-                               return REG_REQ_OK;
-                       return REG_REQ_ALREADY_SET;
-               }
+       if (need_more_processing)
+               schedule_work(&reg_work);
+}
 
-               /*
-                * This would happen if you unplug and plug your card
-                * back in or if you add a new device for which the previously
-                * loaded card also agrees on the regulatory domain.
-                */
-               if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
-                   !regdom_changes(pending_request->alpha2))
-                       return REG_REQ_ALREADY_SET;
+/**
+ * reg_process_hint_core - process core regulatory requests
+ * @pending_request: a pending core regulatory request
+ *
+ * The wireless subsystem can use this function to process
+ * a regulatory request issued by the regulatory core.
+ *
+ * Returns one of the different reg request treatment values.
+ */
+static enum reg_request_treatment
+reg_process_hint_core(struct regulatory_request *core_request)
+{
+
+       core_request->intersect = false;
+       core_request->processed = false;
+
+       reg_update_last_request(core_request);
 
+       return reg_call_crda(core_request);
+}
+
+static enum reg_request_treatment
+__reg_process_hint_user(struct regulatory_request *user_request)
+{
+       struct regulatory_request *lr = get_last_request();
+
+       if (reg_request_cell_base(user_request))
+               return reg_ignore_cell_hint(user_request);
+
+       if (reg_request_cell_base(lr))
+               return REG_REQ_IGNORE;
+
+       if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
                return REG_REQ_INTERSECT;
-       case NL80211_REGDOM_SET_BY_USER:
-               if (reg_request_cell_base(pending_request))
-                       return reg_ignore_cell_hint(pending_request);
+       /*
+        * If the user knows better the user should set the regdom
+        * to their country before the IE is picked up
+        */
+       if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
+           lr->intersect)
+               return REG_REQ_IGNORE;
+       /*
+        * Process user requests only after previous user/driver/core
+        * requests have been processed
+        */
+       if ((lr->initiator == NL80211_REGDOM_SET_BY_CORE ||
+            lr->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
+            lr->initiator == NL80211_REGDOM_SET_BY_USER) &&
+           regdom_changes(lr->alpha2))
+               return REG_REQ_IGNORE;
 
-               if (reg_request_cell_base(lr))
-                       return REG_REQ_IGNORE;
+       if (!regdom_changes(user_request->alpha2))
+               return REG_REQ_ALREADY_SET;
 
-               if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
-                       return REG_REQ_INTERSECT;
-               /*
-                * If the user knows better the user should set the regdom
-                * to their country before the IE is picked up
-                */
-               if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
-                   lr->intersect)
-                       return REG_REQ_IGNORE;
-               /*
-                * Process user requests only after previous user/driver/core
-                * requests have been processed
-                */
-               if ((lr->initiator == NL80211_REGDOM_SET_BY_CORE ||
-                    lr->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
-                    lr->initiator == NL80211_REGDOM_SET_BY_USER) &&
-                   regdom_changes(lr->alpha2))
-                       return REG_REQ_IGNORE;
+       return REG_REQ_OK;
+}
 
-               if (!regdom_changes(pending_request->alpha2))
-                       return REG_REQ_ALREADY_SET;
+/**
+ * reg_process_hint_user - process user regulatory requests
+ * @user_request: a pending user regulatory request
+ *
+ * The wireless subsystem can use this function to process
+ * a regulatory request initiated by userspace.
+ *
+ * Returns one of the different reg request treatment values.
+ */
+static enum reg_request_treatment
+reg_process_hint_user(struct regulatory_request *user_request)
+{
+       enum reg_request_treatment treatment;
 
-               return REG_REQ_OK;
+       treatment = __reg_process_hint_user(user_request);
+       if (treatment == REG_REQ_IGNORE ||
+           treatment == REG_REQ_ALREADY_SET) {
+               kfree(user_request);
+               return treatment;
        }
 
-       return REG_REQ_IGNORE;
+       user_request->intersect = treatment == REG_REQ_INTERSECT;
+       user_request->processed = false;
+
+       reg_update_last_request(user_request);
+
+       user_alpha2[0] = user_request->alpha2[0];
+       user_alpha2[1] = user_request->alpha2[1];
+
+       return reg_call_crda(user_request);
 }
 
-static void reg_set_request_processed(void)
+static enum reg_request_treatment
+__reg_process_hint_driver(struct regulatory_request *driver_request)
 {
-       bool need_more_processing = false;
        struct regulatory_request *lr = get_last_request();
 
-       lr->processed = true;
-
-       spin_lock(&reg_requests_lock);
-       if (!list_empty(&reg_requests_list))
-               need_more_processing = true;
-       spin_unlock(&reg_requests_lock);
+       if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) {
+               if (regdom_changes(driver_request->alpha2))
+                       return REG_REQ_OK;
+               return REG_REQ_ALREADY_SET;
+       }
 
-       if (lr->initiator == NL80211_REGDOM_SET_BY_USER)
-               cancel_delayed_work(&reg_timeout);
+       /*
+        * This would happen if you unplug and plug your card
+        * back in or if you add a new device for which the previously
+        * loaded card also agrees on the regulatory domain.
+        */
+       if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
+           !regdom_changes(driver_request->alpha2))
+               return REG_REQ_ALREADY_SET;
 
-       if (need_more_processing)
-               schedule_work(&reg_work);
+       return REG_REQ_INTERSECT;
 }
 
 /**
- * __regulatory_hint - hint to the wireless core a regulatory domain
- * @wiphy: if the hint comes from country information from an AP, this
- *     is required to be set to the wiphy that received the information
- * @pending_request: the regulatory request currently being processed
+ * reg_process_hint_driver - process driver regulatory requests
+ * @driver_request: a pending driver regulatory request
  *
- * The Wireless subsystem can use this function to hint to the wireless core
- * what it believes should be the current regulatory domain.
+ * The wireless subsystem can use this function to process
+ * a regulatory request issued by an 802.11 driver.
  *
  * Returns one of the different reg request treatment values.
  */
 static enum reg_request_treatment
-__regulatory_hint(struct wiphy *wiphy,
-                 struct regulatory_request *pending_request)
+reg_process_hint_driver(struct wiphy *wiphy,
+                       struct regulatory_request *driver_request)
 {
        const struct ieee80211_regdomain *regd;
-       bool intersect = false;
        enum reg_request_treatment treatment;
-       struct regulatory_request *lr;
 
-       treatment = get_reg_request_treatment(wiphy, pending_request);
+       treatment = __reg_process_hint_driver(driver_request);
 
        switch (treatment) {
-       case REG_REQ_INTERSECT:
-               if (pending_request->initiator ==
-                   NL80211_REGDOM_SET_BY_DRIVER) {
-                       regd = reg_copy_regd(get_cfg80211_regdom());
-                       if (IS_ERR(regd)) {
-                               kfree(pending_request);
-                               return PTR_ERR(regd);
-                       }
-                       rcu_assign_pointer(wiphy->regd, regd);
-               }
-               intersect = true;
-               break;
        case REG_REQ_OK:
                break;
-       default:
-               /*
-                * If the regulatory domain being requested by the
-                * driver has already been set just copy it to the
-                * wiphy
-                */
-               if (treatment == REG_REQ_ALREADY_SET &&
-                   pending_request->initiator == NL80211_REGDOM_SET_BY_DRIVER) {
-                       regd = reg_copy_regd(get_cfg80211_regdom());
-                       if (IS_ERR(regd)) {
-                               kfree(pending_request);
-                               return REG_REQ_IGNORE;
-                       }
-                       treatment = REG_REQ_ALREADY_SET;
-                       rcu_assign_pointer(wiphy->regd, regd);
-                       goto new_request;
-               }
-               kfree(pending_request);
+       case REG_REQ_IGNORE:
+               kfree(driver_request);
                return treatment;
+       case REG_REQ_INTERSECT:
+               /* fall through */
+       case REG_REQ_ALREADY_SET:
+               regd = reg_copy_regd(get_cfg80211_regdom());
+               if (IS_ERR(regd)) {
+                       kfree(driver_request);
+                       return REG_REQ_IGNORE;
+               }
+               rcu_assign_pointer(wiphy->regd, regd);
        }
 
-new_request:
-       lr = get_last_request();
-       if (lr != &core_request_world && lr)
-               kfree_rcu(lr, rcu_head);
 
-       pending_request->intersect = intersect;
-       pending_request->processed = false;
-       rcu_assign_pointer(last_request, pending_request);
-       lr = pending_request;
+       driver_request->intersect = treatment == REG_REQ_INTERSECT;
+       driver_request->processed = false;
 
-       pending_request = NULL;
+       reg_update_last_request(driver_request);
 
-       if (lr->initiator == NL80211_REGDOM_SET_BY_USER) {
-               user_alpha2[0] = lr->alpha2[0];
-               user_alpha2[1] = lr->alpha2[1];
+       /*
+        * Since CRDA will not be called in this case as we already
+        * have applied the requested regulatory domain before we just
+        * inform userspace we have processed the request
+        */
+       if (treatment == REG_REQ_ALREADY_SET) {
+               nl80211_send_reg_change_event(driver_request);
+               reg_set_request_processed();
+               return treatment;
        }
 
-       /* When r == REG_REQ_INTERSECT we do need to call CRDA */
-       if (treatment != REG_REQ_OK && treatment != REG_REQ_INTERSECT) {
+       return reg_call_crda(driver_request);
+}
+
+static enum reg_request_treatment
+__reg_process_hint_country_ie(struct wiphy *wiphy,
+                             struct regulatory_request *country_ie_request)
+{
+       struct wiphy *last_wiphy = NULL;
+       struct regulatory_request *lr = get_last_request();
+
+       if (reg_request_cell_base(lr)) {
+               /* Trust a Cell base station over the AP's country IE */
+               if (regdom_changes(country_ie_request->alpha2))
+                       return REG_REQ_IGNORE;
+               return REG_REQ_ALREADY_SET;
+       } else {
+               if (wiphy->regulatory_flags & REGULATORY_COUNTRY_IE_IGNORE)
+                       return REG_REQ_IGNORE;
+       }
+
+       if (unlikely(!is_an_alpha2(country_ie_request->alpha2)))
+               return -EINVAL;
+
+       if (lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE)
+               return REG_REQ_OK;
+
+       last_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx);
+
+       if (last_wiphy != wiphy) {
                /*
-                * Since CRDA will not be called in this case as we already
-                * have applied the requested regulatory domain before we just
-                * inform userspace we have processed the request
+                * Two cards with two APs claiming different
+                * Country IE alpha2s. We could
+                * intersect them, but that seems unlikely
+                * to be correct. Reject second one for now.
                 */
-               if (treatment == REG_REQ_ALREADY_SET) {
-                       nl80211_send_reg_change_event(lr);
-                       reg_set_request_processed();
-               }
-               return treatment;
+               if (regdom_changes(country_ie_request->alpha2))
+                       return REG_REQ_IGNORE;
+               return REG_REQ_ALREADY_SET;
        }
+       /*
+        * Two consecutive Country IE hints on the same wiphy.
+        * This should be picked up early by the driver/stack
+        */
+       if (WARN_ON(regdom_changes(country_ie_request->alpha2)))
+               return REG_REQ_OK;
+       return REG_REQ_ALREADY_SET;
+}
+
+/**
+ * reg_process_hint_country_ie - process regulatory requests from country IEs
+ * @country_ie_request: a regulatory request from a country IE
+ *
+ * The wireless subsystem can use this function to process
+ * a regulatory request issued by a country Information Element.
+ *
+ * Returns one of the different reg request treatment values.
+ */
+static enum reg_request_treatment
+reg_process_hint_country_ie(struct wiphy *wiphy,
+                           struct regulatory_request *country_ie_request)
+{
+       enum reg_request_treatment treatment;
+
+       treatment = __reg_process_hint_country_ie(wiphy, country_ie_request);
 
-       if (call_crda(lr->alpha2))
+       switch (treatment) {
+       case REG_REQ_OK:
+               break;
+       case REG_REQ_IGNORE:
+               /* fall through */
+       case REG_REQ_ALREADY_SET:
+               kfree(country_ie_request);
+               return treatment;
+       case REG_REQ_INTERSECT:
+               kfree(country_ie_request);
+               /*
+                * This doesn't happen yet, not sure we
+                * ever want to support it for this case.
+                */
+               WARN_ONCE(1, "Unexpected intersection for country IEs");
                return REG_REQ_IGNORE;
-       return REG_REQ_OK;
+       }
+
+       country_ie_request->intersect = false;
+       country_ie_request->processed = false;
+
+       reg_update_last_request(country_ie_request);
+
+       return reg_call_crda(country_ie_request);
 }
 
 /* This processes *all* regulatory hints */
-static void reg_process_hint(struct regulatory_request *reg_request,
-                            enum nl80211_reg_initiator reg_initiator)
+static void reg_process_hint(struct regulatory_request *reg_request)
 {
        struct wiphy *wiphy = NULL;
+       enum reg_request_treatment treatment;
 
        if (WARN_ON(!reg_request->alpha2))
                return;
@@ -1546,23 +1662,37 @@ static void reg_process_hint(struct regulatory_request *reg_request,
        if (reg_request->wiphy_idx != WIPHY_IDX_INVALID)
                wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);
 
-       if (reg_initiator == NL80211_REGDOM_SET_BY_DRIVER && !wiphy) {
+       if (reg_request->initiator == NL80211_REGDOM_SET_BY_DRIVER && !wiphy) {
                kfree(reg_request);
                return;
        }
 
-       switch (__regulatory_hint(wiphy, reg_request)) {
-       case REG_REQ_ALREADY_SET:
-               /* This is required so that the orig_* parameters are saved */
-               if (wiphy && wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
-                       wiphy_update_regulatory(wiphy, reg_initiator);
+       switch (reg_request->initiator) {
+       case NL80211_REGDOM_SET_BY_CORE:
+               reg_process_hint_core(reg_request);
+               return;
+       case NL80211_REGDOM_SET_BY_USER:
+               treatment = reg_process_hint_user(reg_request);
+               if (treatment == REG_REQ_OK ||
+                   treatment == REG_REQ_ALREADY_SET)
+                       return;
+               schedule_delayed_work(&reg_timeout, msecs_to_jiffies(3142));
+               return;
+       case NL80211_REGDOM_SET_BY_DRIVER:
+               treatment = reg_process_hint_driver(wiphy, reg_request);
                break;
-       default:
-               if (reg_initiator == NL80211_REGDOM_SET_BY_USER)
-                       schedule_delayed_work(&reg_timeout,
-                                             msecs_to_jiffies(3142));
+       case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+               treatment = reg_process_hint_country_ie(wiphy, reg_request);
                break;
+       default:
+               WARN(1, "invalid initiator %d\n", reg_request->initiator);
+               return;
        }
+
+       /* This is required so that the orig_* parameters are saved */
+       if (treatment == REG_REQ_ALREADY_SET && wiphy &&
+           wiphy->regulatory_flags & REGULATORY_STRICT_REG)
+               wiphy_update_regulatory(wiphy, reg_request->initiator);
 }
 
 /*
@@ -1596,7 +1726,7 @@ static void reg_process_pending_hints(void)
 
        spin_unlock(&reg_requests_lock);
 
-       reg_process_hint(reg_request, reg_request->initiator);
+       reg_process_hint(reg_request);
 }
 
 /* Processes beacon hints -- this has nothing to do with country IEs */
@@ -1888,7 +2018,7 @@ static void restore_regulatory_settings(bool reset_user)
        world_alpha2[1] = cfg80211_world_regdom->alpha2[1];
 
        list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
-               if (rdev->wiphy.flags & WIPHY_FLAG_CUSTOM_REGULATORY)
+               if (rdev->wiphy.regulatory_flags & REGULATORY_CUSTOM_REG)
                        restore_custom_reg_settings(&rdev->wiphy);
        }
 
@@ -2016,7 +2146,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
        }
 }
 
-bool reg_supported_dfs_region(u8 dfs_region)
+bool reg_supported_dfs_region(enum nl80211_dfs_regions dfs_region)
 {
        switch (dfs_region) {
        case NL80211_DFS_UNSET:
@@ -2031,27 +2161,6 @@ bool reg_supported_dfs_region(u8 dfs_region)
        }
 }
 
-static void print_dfs_region(u8 dfs_region)
-{
-       if (!dfs_region)
-               return;
-
-       switch (dfs_region) {
-       case NL80211_DFS_FCC:
-               pr_info(" DFS Master region FCC");
-               break;
-       case NL80211_DFS_ETSI:
-               pr_info(" DFS Master region ETSI");
-               break;
-       case NL80211_DFS_JP:
-               pr_info(" DFS Master region JP");
-               break;
-       default:
-               pr_info(" DFS Master region Unknown");
-               break;
-       }
-}
-
 static void print_regdomain(const struct ieee80211_regdomain *rd)
 {
        struct regulatory_request *lr = get_last_request();
@@ -2083,7 +2192,7 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
                }
        }
 
-       print_dfs_region(rd->dfs_region);
+       pr_info(" DFS Master region: %s", reg_dfs_region_str(rd->dfs_region));
        print_rd_rules(rd);
 }
 
@@ -2093,48 +2202,60 @@ static void print_regdomain_info(const struct ieee80211_regdomain *rd)
        print_rd_rules(rd);
 }
 
-/* Takes ownership of rd only if it doesn't fail */
-static int __set_regdom(const struct ieee80211_regdomain *rd)
+static int reg_set_rd_core(const struct ieee80211_regdomain *rd)
+{
+       if (!is_world_regdom(rd->alpha2))
+               return -EINVAL;
+       update_world_regdomain(rd);
+       return 0;
+}
+
+static int reg_set_rd_user(const struct ieee80211_regdomain *rd,
+                          struct regulatory_request *user_request)
 {
-       const struct ieee80211_regdomain *regd;
        const struct ieee80211_regdomain *intersected_rd = NULL;
-       struct wiphy *request_wiphy;
-       struct regulatory_request *lr = get_last_request();
 
-       /* Some basic sanity checks first */
+       if (is_world_regdom(rd->alpha2))
+               return -EINVAL;
+
+       if (!regdom_changes(rd->alpha2))
+               return -EALREADY;
 
-       if (!reg_is_valid_request(rd->alpha2))
+       if (!is_valid_rd(rd)) {
+               pr_err("Invalid regulatory domain detected:\n");
+               print_regdomain_info(rd);
                return -EINVAL;
+       }
 
-       if (is_world_regdom(rd->alpha2)) {
-               update_world_regdomain(rd);
+       if (!user_request->intersect) {
+               reset_regdomains(false, rd);
                return 0;
        }
 
-       if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) &&
-           !is_unknown_alpha2(rd->alpha2))
+       intersected_rd = regdom_intersect(rd, get_cfg80211_regdom());
+       if (!intersected_rd)
                return -EINVAL;
 
-       /*
-        * Lets only bother proceeding on the same alpha2 if the current
-        * rd is non static (it means CRDA was present and was used last)
-        * and the pending request came in from a country IE
-        */
-       if (lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
-               /*
-                * If someone else asked us to change the rd lets only bother
-                * checking if the alpha2 changes if CRDA was already called
-                */
-               if (!regdom_changes(rd->alpha2))
-                       return -EALREADY;
-       }
+       kfree(rd);
+       rd = NULL;
+       reset_regdomains(false, intersected_rd);
 
-       /*
-        * Now lets set the regulatory domain, update all driver channels
-        * and finally inform them of what we have done, in case they want
-        * to review or adjust their own settings based on their own
-        * internal EEPROM data
-        */
+       return 0;
+}
+
+static int reg_set_rd_driver(const struct ieee80211_regdomain *rd,
+                            struct regulatory_request *driver_request)
+{
+       const struct ieee80211_regdomain *regd;
+       const struct ieee80211_regdomain *intersected_rd = NULL;
+       const struct ieee80211_regdomain *tmp;
+       struct wiphy *request_wiphy;
+
+       if (is_world_regdom(rd->alpha2))
+               return -EINVAL;
+
+       if (!regdom_changes(rd->alpha2))
+               return -EALREADY;
 
        if (!is_valid_rd(rd)) {
                pr_err("Invalid regulatory domain detected:\n");
@@ -2142,29 +2263,13 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
                return -EINVAL;
        }
 
-       request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx);
-       if (!request_wiphy &&
-           (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
-            lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) {
+       request_wiphy = wiphy_idx_to_wiphy(driver_request->wiphy_idx);
+       if (!request_wiphy) {
                schedule_delayed_work(&reg_timeout, 0);
                return -ENODEV;
        }
 
-       if (!lr->intersect) {
-               if (lr->initiator != NL80211_REGDOM_SET_BY_DRIVER) {
-                       reset_regdomains(false, rd);
-                       return 0;
-               }
-
-               /*
-                * For a driver hint, lets copy the regulatory domain the
-                * driver wanted to the wiphy to deal with conflicts
-                */
-
-               /*
-                * Userspace could have sent two replies with only
-                * one kernel request.
-                */
+       if (!driver_request->intersect) {
                if (request_wiphy->regd)
                        return -EALREADY;
 
@@ -2177,38 +2282,59 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
                return 0;
        }
 
-       /* Intersection requires a bit more work */
+       intersected_rd = regdom_intersect(rd, get_cfg80211_regdom());
+       if (!intersected_rd)
+               return -EINVAL;
 
-       if (lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
-               intersected_rd = regdom_intersect(rd, get_cfg80211_regdom());
-               if (!intersected_rd)
-                       return -EINVAL;
+       /*
+        * We can trash what CRDA provided now.
+        * However if a driver requested this specific regulatory
+        * domain we keep it for its private use
+        */
+       tmp = get_wiphy_regdom(request_wiphy);
+       rcu_assign_pointer(request_wiphy->regd, rd);
+       rcu_free_regdom(tmp);
 
-               /*
-                * We can trash what CRDA provided now.
-                * However if a driver requested this specific regulatory
-                * domain we keep it for its private use
-                */
-               if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER) {
-                       const struct ieee80211_regdomain *tmp;
+       rd = NULL;
 
-                       tmp = get_wiphy_regdom(request_wiphy);
-                       rcu_assign_pointer(request_wiphy->regd, rd);
-                       rcu_free_regdom(tmp);
-               } else {
-                       kfree(rd);
-               }
+       reset_regdomains(false, intersected_rd);
 
-               rd = NULL;
+       return 0;
+}
 
-               reset_regdomains(false, intersected_rd);
+static int reg_set_rd_country_ie(const struct ieee80211_regdomain *rd,
+                                struct regulatory_request *country_ie_request)
+{
+       struct wiphy *request_wiphy;
 
-               return 0;
+       if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) &&
+           !is_unknown_alpha2(rd->alpha2))
+               return -EINVAL;
+
+       /*
+        * Lets only bother proceeding on the same alpha2 if the current
+        * rd is non static (it means CRDA was present and was used last)
+        * and the pending request came in from a country IE
+        */
+
+       if (!is_valid_rd(rd)) {
+               pr_err("Invalid regulatory domain detected:\n");
+               print_regdomain_info(rd);
+               return -EINVAL;
        }
 
-       return -EINVAL;
-}
+       request_wiphy = wiphy_idx_to_wiphy(country_ie_request->wiphy_idx);
+       if (!request_wiphy) {
+               schedule_delayed_work(&reg_timeout, 0);
+               return -ENODEV;
+       }
+
+       if (country_ie_request->intersect)
+               return -EINVAL;
 
+       reset_regdomains(false, rd);
+       return 0;
+}
 
 /*
  * Use this call to set the current regulatory domain. Conflicts with
@@ -2220,10 +2346,32 @@ int set_regdom(const struct ieee80211_regdomain *rd)
        struct regulatory_request *lr;
        int r;
 
+       if (!reg_is_valid_request(rd->alpha2)) {
+               kfree(rd);
+               return -EINVAL;
+       }
+
        lr = get_last_request();
 
        /* Note that this doesn't update the wiphys, this is done below */
-       r = __set_regdom(rd);
+       switch (lr->initiator) {
+       case NL80211_REGDOM_SET_BY_CORE:
+               r = reg_set_rd_core(rd);
+               break;
+       case NL80211_REGDOM_SET_BY_USER:
+               r = reg_set_rd_user(rd, lr);
+               break;
+       case NL80211_REGDOM_SET_BY_DRIVER:
+               r = reg_set_rd_driver(rd, lr);
+               break;
+       case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+               r = reg_set_rd_country_ie(rd, lr);
+               break;
+       default:
+               WARN(1, "invalid initiator %d\n", lr->initiator);
+               return -EINVAL;
+       }
+
        if (r) {
                if (r == -EALREADY)
                        reg_set_request_processed();
index 9677e3c13da98da5b00f34e112b0562512b6fc65..cc4c2c0a67236cd2801f954e0a8e15dc4b5adea5 100644 (file)
@@ -18,8 +18,9 @@
 
 extern const struct ieee80211_regdomain __rcu *cfg80211_regdomain;
 
+bool reg_is_valid_request(const char *alpha2);
 bool is_world_regdom(const char *alpha2);
-bool reg_supported_dfs_region(u8 dfs_region);
+bool reg_supported_dfs_region(enum nl80211_dfs_regions dfs_region);
 
 int regulatory_hint_user(const char *alpha2,
                         enum nl80211_user_reg_hint_type user_reg_hint_type);
index ba5f0d6614d5d4cee4d08c609bb192dd501f0b34..f7aa7a72d9bc928aa7d24153d709e13634773b06 100644 (file)
@@ -1653,9 +1653,8 @@ TRACE_EVENT(rdev_cancel_remain_on_channel,
 
 TRACE_EVENT(rdev_mgmt_tx,
        TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
-                struct ieee80211_channel *chan, bool offchan,
-                unsigned int wait, bool no_cck, bool dont_wait_for_ack),
-       TP_ARGS(wiphy, wdev, chan, offchan, wait, no_cck, dont_wait_for_ack),
+                struct cfg80211_mgmt_tx_params *params),
+       TP_ARGS(wiphy, wdev, params),
        TP_STRUCT__entry(
                WIPHY_ENTRY
                WDEV_ENTRY
@@ -1668,11 +1667,11 @@ TRACE_EVENT(rdev_mgmt_tx,
        TP_fast_assign(
                WIPHY_ASSIGN;
                WDEV_ASSIGN;
-               CHAN_ASSIGN(chan);
-               __entry->offchan = offchan;
-               __entry->wait = wait;
-               __entry->no_cck = no_cck;
-               __entry->dont_wait_for_ack = dont_wait_for_ack;
+               CHAN_ASSIGN(params->chan);
+               __entry->offchan = params->offchan;
+               __entry->wait = params->wait;
+               __entry->no_cck = params->no_cck;
+               __entry->dont_wait_for_ack = params->dont_wait_for_ack;
        ),
        TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", offchan: %s,"
                  " wait: %u, no cck: %s, dont wait for ack: %s",