From 92ca4f93474a63dcd717c076ee8d0e6ab7c93ccf Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 9 Mar 2012 11:59:15 +0200 Subject: [PATCH] --- yaml --- r: 306827 b: refs/heads/master c: e46668819c1bd5930720a7e020e2a45291f9de4f h: refs/heads/master i: 306825: e277c60c8c1cb85eea218bcefed1bfd57015d212 306823: f6a1db72ef1484b21951e9631eaf09e8181c169c v: v3 --- [refs] | 2 +- .../feature-removal-schedule.txt | 12 - trunk/Documentation/nfc/nfc-hci.txt | 45 +- trunk/arch/mips/bcm47xx/setup.c | 15 +- trunk/arch/mips/bcm47xx/sprom.c | 28 +- .../mips/include/asm/mach-bcm47xx/bcm47xx.h | 9 - trunk/drivers/bcma/core.c | 3 +- trunk/drivers/bcma/driver_pci.c | 53 +- trunk/drivers/bcma/driver_pci_host.c | 10 +- trunk/drivers/bcma/host_pci.c | 7 +- trunk/drivers/bcma/scan.c | 54 +- trunk/drivers/bcma/sprom.c | 149 +-- .../net/wireless/ath/ath6kl/cfg80211.c | 238 ++--- .../net/wireless/ath/ath6kl/cfg80211.h | 2 - trunk/drivers/net/wireless/ath/ath6kl/core.h | 33 +- trunk/drivers/net/wireless/ath/ath6kl/debug.c | 12 +- .../net/wireless/ath/ath6kl/htc_mbox.c | 45 +- .../net/wireless/ath/ath6kl/htc_pipe.c | 11 +- trunk/drivers/net/wireless/ath/ath6kl/init.c | 29 +- trunk/drivers/net/wireless/ath/ath6kl/main.c | 104 +- trunk/drivers/net/wireless/ath/ath6kl/sdio.c | 17 +- trunk/drivers/net/wireless/ath/ath6kl/txrx.c | 12 +- trunk/drivers/net/wireless/ath/ath6kl/usb.c | 12 - trunk/drivers/net/wireless/ath/ath6kl/wmi.c | 94 +- trunk/drivers/net/wireless/ath/ath6kl/wmi.h | 24 - .../net/wireless/ath/ath9k/ar9003_calib.c | 50 +- .../net/wireless/ath/ath9k/ar9003_mci.c | 2 +- .../net/wireless/ath/ath9k/ar9003_rtt.c | 84 +- .../net/wireless/ath/ath9k/ar9003_rtt.h | 5 +- trunk/drivers/net/wireless/ath/ath9k/hw.c | 9 +- trunk/drivers/net/wireless/ath/ath9k/hw.h | 9 +- trunk/drivers/net/wireless/b43/bus.c | 6 +- trunk/drivers/net/wireless/b43/dma.c | 2 +- trunk/drivers/net/wireless/b43/main.c | 4 +- trunk/drivers/net/wireless/b43legacy/main.c | 4 +- trunk/drivers/net/wireless/b43legacy/phy.c | 4 +- trunk/drivers/net/wireless/b43legacy/radio.c | 10 +- .../net/wireless/brcm80211/brcmfmac/bcmsdh.c | 244 ++--- .../brcm80211/brcmfmac/bcmsdh_sdmmc.c | 32 +- .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 350 ++++--- .../wireless/brcm80211/brcmfmac/sdio_chip.c | 265 +++-- .../wireless/brcm80211/brcmfmac/sdio_host.h | 37 +- .../net/wireless/brcm80211/brcmsmac/Makefile | 3 + .../net/wireless/brcm80211/brcmsmac/aiutils.c | 479 ++++++++- .../net/wireless/brcm80211/brcmsmac/aiutils.h | 24 + .../net/wireless/brcm80211/brcmsmac/antsel.c | 16 +- .../net/wireless/brcm80211/brcmsmac/channel.c | 7 +- .../wireless/brcm80211/brcmsmac/mac80211_if.c | 11 +- .../net/wireless/brcm80211/brcmsmac/main.c | 142 +-- .../net/wireless/brcm80211/brcmsmac/nicpci.c | 826 +++++++++++++++ .../net/wireless/brcm80211/brcmsmac/nicpci.h | 77 ++ .../net/wireless/brcm80211/brcmsmac/otp.c | 410 ++++++++ .../net/wireless/brcm80211/brcmsmac/otp.h | 36 + .../wireless/brcm80211/brcmsmac/phy/phy_lcn.c | 67 +- .../wireless/brcm80211/brcmsmac/phy/phy_n.c | 333 ++++-- .../wireless/brcm80211/brcmsmac/phy_shim.c | 9 + .../wireless/brcm80211/brcmsmac/phy_shim.h | 3 + .../net/wireless/brcm80211/brcmsmac/pub.h | 228 ++++ .../net/wireless/brcm80211/brcmsmac/srom.c | 980 ++++++++++++++++++ .../net/wireless/brcm80211/brcmsmac/srom.h | 29 + .../net/wireless/brcm80211/brcmsmac/stf.c | 6 +- .../net/wireless/iwlwifi/iwl-agn-lib.c | 35 +- .../net/wireless/iwlwifi/iwl-agn-rxon.c | 4 - .../drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 19 +- trunk/drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- .../net/wireless/iwlwifi/iwl-commands.h | 7 +- .../net/wireless/iwlwifi/iwl-mac80211.c | 5 +- .../drivers/net/wireless/iwlwifi/iwl-power.c | 8 +- trunk/drivers/net/wireless/iwlwifi/iwl-scan.c | 52 +- trunk/drivers/net/wireless/mac80211_hwsim.c | 5 - trunk/drivers/net/wireless/mwifiex/Makefile | 2 - trunk/drivers/net/wireless/mwifiex/cfg80211.c | 498 +++------ trunk/drivers/net/wireless/mwifiex/cfg80211.h | 2 +- trunk/drivers/net/wireless/mwifiex/cmdevt.c | 21 +- trunk/drivers/net/wireless/mwifiex/decl.h | 13 +- trunk/drivers/net/wireless/mwifiex/fw.h | 159 +-- trunk/drivers/net/wireless/mwifiex/ie.c | 396 ------- trunk/drivers/net/wireless/mwifiex/init.c | 1 - trunk/drivers/net/wireless/mwifiex/ioctl.h | 32 - trunk/drivers/net/wireless/mwifiex/join.c | 26 +- trunk/drivers/net/wireless/mwifiex/main.c | 57 +- trunk/drivers/net/wireless/mwifiex/main.h | 26 +- trunk/drivers/net/wireless/mwifiex/sta_cmd.c | 69 +- .../net/wireless/mwifiex/sta_cmdresp.c | 8 - .../drivers/net/wireless/mwifiex/sta_event.c | 51 +- .../drivers/net/wireless/mwifiex/sta_ioctl.c | 9 +- trunk/drivers/net/wireless/mwifiex/uap_cmd.c | 432 -------- trunk/drivers/net/wireless/mwifiex/wmm.c | 4 - trunk/drivers/net/wireless/rndis_wlan.c | 14 + trunk/drivers/net/wireless/rt2x00/rt2800pci.c | 1 - trunk/drivers/net/wireless/ti/wl12xx/Kconfig | 1 - trunk/drivers/net/wireless/ti/wlcore/Kconfig | 2 +- trunk/drivers/net/wireless/ti/wlcore/acx.c | 80 -- trunk/drivers/net/wireless/ti/wlcore/acx.h | 30 - trunk/drivers/net/wireless/ti/wlcore/boot.c | 3 +- trunk/drivers/net/wireless/ti/wlcore/cmd.c | 8 +- trunk/drivers/net/wireless/ti/wlcore/event.c | 29 +- trunk/drivers/net/wireless/ti/wlcore/main.c | 323 +----- trunk/drivers/net/wireless/ti/wlcore/rx.c | 36 - trunk/drivers/net/wireless/ti/wlcore/rx.h | 4 - trunk/drivers/net/wireless/ti/wlcore/wl12xx.h | 41 - trunk/drivers/net/wireless/ti/wlcore/wlcore.h | 6 - trunk/drivers/nfc/Kconfig | 13 - trunk/drivers/nfc/Makefile | 1 - trunk/drivers/nfc/pn533.c | 19 +- trunk/drivers/nfc/pn544_hci.c | 947 ----------------- trunk/drivers/ssb/b43_pci_bridge.c | 2 - trunk/drivers/ssb/pci.c | 88 +- trunk/include/linux/Kbuild | 1 - trunk/include/linux/bcma/bcma.h | 7 - trunk/include/linux/bcma/bcma_driver_pci.h | 11 - trunk/include/linux/nfc/pn544.h | 7 - trunk/include/linux/nl80211.h | 8 +- trunk/include/linux/ssb/ssb.h | 1 + trunk/include/linux/ssb/ssb_regs.h | 61 +- trunk/include/net/cfg80211.h | 6 +- trunk/include/net/mac80211.h | 12 +- trunk/include/net/nfc/hci.h | 6 +- trunk/include/net/nfc/nfc.h | 19 +- trunk/include/net/nfc/shdlc.h | 2 - trunk/net/bluetooth/hci_event.c | 2 +- trunk/net/mac80211/agg-tx.c | 10 +- trunk/net/mac80211/debugfs_netdev.c | 2 - trunk/net/mac80211/ibss.c | 5 - trunk/net/mac80211/iface.c | 4 +- trunk/net/mac80211/main.c | 3 - trunk/net/mac80211/mesh.c | 6 +- trunk/net/mac80211/mesh_hwmp.c | 5 +- trunk/net/mac80211/mesh_plink.c | 65 +- trunk/net/mac80211/rx.c | 6 +- trunk/net/mac80211/wep.c | 15 +- trunk/net/mac80211/wpa.c | 10 +- trunk/net/nfc/core.c | 112 +- trunk/net/nfc/hci/Kconfig | 1 - trunk/net/nfc/hci/core.c | 78 +- trunk/net/nfc/hci/shdlc.c | 12 - trunk/net/nfc/llcp/commands.c | 4 +- trunk/net/nfc/llcp/llcp.c | 7 - trunk/net/nfc/llcp/sock.c | 57 +- trunk/net/nfc/nci/core.c | 27 +- trunk/net/nfc/nci/data.c | 8 +- trunk/net/nfc/nci/lib.c | 1 - trunk/net/nfc/nci/ntf.c | 2 +- trunk/net/nfc/netlink.c | 6 +- trunk/net/nfc/nfc.h | 2 +- trunk/net/wireless/chan.c | 2 +- trunk/net/wireless/core.c | 4 +- trunk/net/wireless/core.h | 2 + trunk/net/wireless/nl80211.c | 69 +- trunk/net/wireless/util.c | 2 +- 150 files changed, 4774 insertions(+), 5310 deletions(-) create mode 100644 trunk/drivers/net/wireless/brcm80211/brcmsmac/nicpci.c create mode 100644 trunk/drivers/net/wireless/brcm80211/brcmsmac/nicpci.h create mode 100644 trunk/drivers/net/wireless/brcm80211/brcmsmac/otp.c create mode 100644 trunk/drivers/net/wireless/brcm80211/brcmsmac/otp.h create mode 100644 trunk/drivers/net/wireless/brcm80211/brcmsmac/srom.c create mode 100644 trunk/drivers/net/wireless/brcm80211/brcmsmac/srom.h delete mode 100644 trunk/drivers/net/wireless/mwifiex/ie.c delete mode 100644 trunk/drivers/net/wireless/mwifiex/uap_cmd.c delete mode 100644 trunk/drivers/nfc/pn544_hci.c diff --git a/[refs] b/[refs] index 9b5f0810242d..59810a30420e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4416f5d2ac986923fcb6e42419c8a048dfda7584 +refs/heads/master: e46668819c1bd5930720a7e020e2a45291f9de4f diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 968ed08f0aad..03ca210406ed 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -534,18 +534,6 @@ Who: Kees Cook ---------------------------- -What: Removing the pn544 raw driver. -When: 3.6 -Why: With the introduction of the NFC HCI and SHDL kernel layers, pn544.c - is being replaced by pn544_hci.c which is accessible through the netlink - and socket NFC APIs. Moreover, pn544.c is outdated and does not seem to - work properly with the latest Android stacks. - Having 2 drivers for the same hardware is confusing and as such we - should only keep the one following the kernel NFC APIs. -Who: Samuel Ortiz - ----------------------------- - What: setitimer accepts user NULL pointer (value) When: 3.6 Why: setitimer is not returning -EFAULT if user pointer is NULL. This diff --git a/trunk/Documentation/nfc/nfc-hci.txt b/trunk/Documentation/nfc/nfc-hci.txt index 320f9336c781..216b7254fcc3 100644 --- a/trunk/Documentation/nfc/nfc-hci.txt +++ b/trunk/Documentation/nfc/nfc-hci.txt @@ -22,9 +22,9 @@ response to arrive. HCI events can also be received from the host controller. They will be handled and a translation will be forwarded to NFC Core as needed. HCI uses 2 execution contexts: -- one for executing commands : nfc_hci_msg_tx_work(). Only one command +- one if for executing commands : nfc_hci_msg_tx_work(). Only one command can be executing at any given moment. -- one for dispatching received events and commands : nfc_hci_msg_rx_work(). +- one if for dispatching received events and responses : nfc_hci_msg_rx_work() HCI Session initialization: --------------------------- @@ -52,42 +52,18 @@ entry points: struct nfc_hci_ops { int (*open)(struct nfc_hci_dev *hdev); void (*close)(struct nfc_hci_dev *hdev); - int (*hci_ready) (struct nfc_hci_dev *hdev); int (*xmit)(struct nfc_hci_dev *hdev, struct sk_buff *skb); int (*start_poll)(struct nfc_hci_dev *hdev, u32 protocols); int (*target_from_gate)(struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target); - int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate, - struct nfc_target *target); - int (*data_exchange) (struct nfc_hci_dev *hdev, - struct nfc_target *target, - struct sk_buff *skb, struct sk_buff **res_skb); - int (*check_presence)(struct nfc_hci_dev *hdev, - struct nfc_target *target); }; -- open() and close() shall turn the hardware on and off. -- hci_ready() is an optional entry point that is called right after the hci -session has been set up. The driver can use it to do additional initialization -that must be performed using HCI commands. -- xmit() shall simply write a frame to the chip. -- start_poll() is an optional entrypoint that shall set the hardware in polling -mode. This must be implemented only if the hardware uses proprietary gates or a -mechanism slightly different from the HCI standard. -- target_from_gate() is an optional entrypoint to return the nfc protocols +open() and close() shall turn the hardware on and off. xmit() shall simply +write a frame to the chip. start_poll() is an optional entrypoint that shall +set the hardware in polling mode. This must be implemented only if the hardware +uses proprietary gates or a mechanism slightly different from the HCI standard. +target_from_gate() is another optional entrypoint to return the protocols corresponding to a proprietary gate. -- complete_target_discovered() is an optional entry point to let the driver -perform additional proprietary processing necessary to auto activate the -discovered target. -- data_exchange() must be implemented by the driver if proprietary HCI commands -are required to send data to the tag. Some tag types will require custom -commands, others can be written to using the standard HCI commands. The driver -can check the tag type and either do proprietary processing, or return 1 to ask -for standard processing. -- check_presence() is an optional entry point that will be called regularly -by the core to check that an activated tag is still in the field. If this is -not implemented, the core will not be able to push tag_lost events to the user -space On the rx path, the driver is responsible to push incoming HCP frames to HCI using nfc_hci_recv_frame(). HCI will take care of re-aggregation and handling @@ -123,8 +99,7 @@ fast, cannot sleep. stores incoming frames into an shdlc rx queue handles shdlc rx & tx queues. Dispatches HCI cmd responses. - HCI Tx Cmd worker (MSGTXWQ) -Serializes execution of HCI commands. Completes execution in case of response -timeout. +Serialize execution of HCI commands. Complete execution in case of resp timeout. - HCI Rx worker (MSGRXWQ) Dispatches incoming HCI commands or events. @@ -158,11 +133,11 @@ able to complete the command with a timeout error if no response arrive. SMW context gets scheduled and invokes nfc_shdlc_sm_work(). This function handles shdlc framing in and out. It uses the driver xmit to send frames and receives incoming frames in an skb queue filled from the driver IRQ handler. -SHDLC I(nformation) frames payload are HCP fragments. They are aggregated to +SHDLC I(nformation) frames payload are HCP fragments. They are agregated to form complete HCI frames, which can be a response, command, or event. HCI Responses are dispatched immediately from this context to unblock -waiting command execution. Response processing involves invoking the completion +waiting command execution. Reponse processing involves invoking the completion callback that was provided by nfc_hci_msg_tx_work() when it sent the command. The completion callback will then wake the syscall context. diff --git a/trunk/arch/mips/bcm47xx/setup.c b/trunk/arch/mips/bcm47xx/setup.c index 95bf4d7bac21..19780aa91708 100644 --- a/trunk/arch/mips/bcm47xx/setup.c +++ b/trunk/arch/mips/bcm47xx/setup.c @@ -90,7 +90,6 @@ static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) char prefix[10]; if (bus->bustype == SSB_BUSTYPE_PCI) { - memset(out, 0, sizeof(struct ssb_sprom)); snprintf(prefix, sizeof(prefix), "pci/%u/%u/", bus->host_pci->bus->number + 1, PCI_SLOT(bus->host_pci->devfn)); @@ -110,9 +109,15 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus, /* Fill boardinfo structure */ memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo)); - bcm47xx_fill_ssb_boardinfo(&iv->boardinfo, NULL); + if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0) + iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0); + else + iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM; + if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) + iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); + if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0) + iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); - memset(&iv->sprom, 0, sizeof(struct ssb_sprom)); bcm47xx_fill_sprom(&iv->sprom, NULL); if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) @@ -161,14 +166,12 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) switch (bus->hosttype) { case BCMA_HOSTTYPE_PCI: - memset(out, 0, sizeof(struct ssb_sprom)); snprintf(prefix, sizeof(prefix), "pci/%u/%u/", bus->host_pci->bus->number + 1, PCI_SLOT(bus->host_pci->devfn)); bcm47xx_fill_sprom(out, prefix); return 0; case BCMA_HOSTTYPE_SOC: - memset(out, 0, sizeof(struct ssb_sprom)); bcm47xx_fill_sprom_ethernet(out, NULL); core = bcma_find_core(bus, BCMA_CORE_80211); if (core) { @@ -194,8 +197,6 @@ static void __init bcm47xx_register_bcma(void) err = bcma_host_soc_register(&bcm47xx_bus.bcma); if (err) panic("Failed to initialize BCMA bus (err %d)", err); - - bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL); } #endif diff --git a/trunk/arch/mips/bcm47xx/sprom.c b/trunk/arch/mips/bcm47xx/sprom.c index d3a889745e20..5c8dcd2a8a93 100644 --- a/trunk/arch/mips/bcm47xx/sprom.c +++ b/trunk/arch/mips/bcm47xx/sprom.c @@ -165,8 +165,6 @@ static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom, const char *prefix) { nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0); - if (!sprom->board_rev) - nvram_read_u16(NULL, NULL, "boardrev", &sprom->board_rev, 0); nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0); nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff); nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff); @@ -557,6 +555,8 @@ void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix) void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) { + memset(sprom, 0, sizeof(struct ssb_sprom)); + bcm47xx_fill_sprom_ethernet(sprom, prefix); nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0); @@ -618,27 +618,3 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) bcm47xx_fill_sprom_r1(sprom, prefix); } } - -#ifdef CONFIG_BCM47XX_SSB -void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo, - const char *prefix) -{ - nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0); - if (!boardinfo->vendor) - boardinfo->vendor = SSB_BOARDVENDOR_BCM; - - nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0); -} -#endif - -#ifdef CONFIG_BCM47XX_BCMA -void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, - const char *prefix) -{ - nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0); - if (!boardinfo->vendor) - boardinfo->vendor = SSB_BOARDVENDOR_BCM; - - nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0); -} -#endif diff --git a/trunk/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/trunk/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h index 26fdaf40b930..5ecaf47b34d2 100644 --- a/trunk/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +++ b/trunk/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h @@ -47,13 +47,4 @@ extern enum bcm47xx_bus_type bcm47xx_bus_type; void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix); void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix); -#ifdef CONFIG_BCM47XX_SSB -void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo, - const char *prefix); -#endif -#ifdef CONFIG_BCM47XX_BCMA -void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, - const char *prefix); -#endif - #endif /* __ASM_BCM47XX_H */ diff --git a/trunk/drivers/bcma/core.c b/trunk/drivers/bcma/core.c index bc6e89212ad3..893f6e0c759f 100644 --- a/trunk/drivers/bcma/core.c +++ b/trunk/drivers/bcma/core.c @@ -30,7 +30,6 @@ void bcma_core_disable(struct bcma_device *core, u32 flags) udelay(10); bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET); - bcma_aread32(core, BCMA_RESET_CTL); udelay(1); } EXPORT_SYMBOL_GPL(bcma_core_disable); @@ -78,7 +77,7 @@ void bcma_core_set_clockmode(struct bcma_device *core, pr_err("HT force timeout\n"); break; case BCMA_CLKMODE_DYNAMIC: - bcma_set32(core, BCMA_CLKCTLST, ~BCMA_CLKCTLST_FORCEHT); + pr_warn("Dynamic clockmode not supported yet!\n"); break; } } diff --git a/trunk/drivers/bcma/driver_pci.c b/trunk/drivers/bcma/driver_pci.c index 9a96f14c8f47..4d38ae179b48 100644 --- a/trunk/drivers/bcma/driver_pci.c +++ b/trunk/drivers/bcma/driver_pci.c @@ -24,12 +24,14 @@ u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address) return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA); } +#if 0 static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data) { pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address); pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR); pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data); } +#endif static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy) { @@ -168,50 +170,13 @@ static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc) tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN); } -static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc) -{ - struct bcma_device *core = pc->core; - u16 val16, core_index; - uint regoff; - - regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET); - core_index = (u16)core->core_index; - - val16 = pcicore_read16(pc, regoff); - if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT) - != core_index) { - val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) | - (val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK); - pcicore_write16(pc, regoff, val16); - } -} - -/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */ -/* Needs to happen when coming out of 'standby'/'hibernate' */ -static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc) -{ - u16 val16; - uint regoff; - - regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_MISC_CONFIG); - - val16 = pcicore_read16(pc, regoff); - - if (!(val16 & BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST)) { - val16 |= BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST; - pcicore_write16(pc, regoff, val16); - } -} - /************************************************** * Init. **************************************************/ static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc) { - bcma_core_pci_fixcfg(pc); bcma_pcicore_serdes_workaround(pc); - bcma_core_pci_config_fixup(pc); } void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc) @@ -259,17 +224,3 @@ int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, return err; } EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl); - -void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend) -{ - u32 w; - - w = bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG); - if (extend) - w |= BCMA_CORE_PCI_ASPMTIMER_EXTEND; - else - w &= ~BCMA_CORE_PCI_ASPMTIMER_EXTEND; - bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w); - bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG); -} -EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer); diff --git a/trunk/drivers/bcma/driver_pci_host.c b/trunk/drivers/bcma/driver_pci_host.c index b9a86edfec39..d2097a11c3c7 100644 --- a/trunk/drivers/bcma/driver_pci_host.c +++ b/trunk/drivers/bcma/driver_pci_host.c @@ -119,7 +119,7 @@ static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev, if (unlikely(!addr)) goto out; err = -ENOMEM; - mmio = ioremap_nocache(addr, sizeof(val)); + mmio = ioremap_nocache(addr, len); if (!mmio) goto out; @@ -171,7 +171,7 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0; addr |= (func << 8); addr |= (off & 0xfc); - mmio = ioremap_nocache(addr, sizeof(val)); + mmio = ioremap_nocache(addr, len); if (!mmio) goto out; } @@ -180,7 +180,7 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, if (unlikely(!addr)) goto out; err = -ENOMEM; - mmio = ioremap_nocache(addr, sizeof(val)); + mmio = ioremap_nocache(addr, len); if (!mmio) goto out; @@ -491,8 +491,8 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) /* Ok, ready to run, register it to the system. * The following needs change, if we want to port hostmode * to non-MIPS platform. */ - io_map_base = (unsigned long)ioremap_nocache(pc_host->mem_resource.start, - resource_size(&pc_host->mem_resource)); + io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM, + 0x04000000); pc_host->pci_controller.io_map_base = io_map_base; set_io_port_base(pc_host->pci_controller.io_map_base); /* Give some time to the PCI controller to configure itself with the new diff --git a/trunk/drivers/bcma/host_pci.c b/trunk/drivers/bcma/host_pci.c index 6c05cf470f96..e3928d68802b 100644 --- a/trunk/drivers/bcma/host_pci.c +++ b/trunk/drivers/bcma/host_pci.c @@ -201,9 +201,6 @@ static int __devinit bcma_host_pci_probe(struct pci_dev *dev, bus->hosttype = BCMA_HOSTTYPE_PCI; bus->ops = &bcma_host_pci_ops; - bus->boardinfo.vendor = bus->host_pci->subsystem_vendor; - bus->boardinfo.type = bus->host_pci->subsystem_device; - /* Register */ err = bcma_bus_register(bus); if (err) @@ -225,7 +222,7 @@ static int __devinit bcma_host_pci_probe(struct pci_dev *dev, return err; } -static void __devexit bcma_host_pci_remove(struct pci_dev *dev) +static void bcma_host_pci_remove(struct pci_dev *dev) { struct bcma_bus *bus = pci_get_drvdata(dev); @@ -280,7 +277,7 @@ static struct pci_driver bcma_pci_bridge_driver = { .name = "bcma-pci-bridge", .id_table = bcma_pci_bridge_tbl, .probe = bcma_host_pci_probe, - .remove = __devexit_p(bcma_host_pci_remove), + .remove = bcma_host_pci_remove, .driver.pm = BCMA_PM_OPS, }; diff --git a/trunk/drivers/bcma/scan.c b/trunk/drivers/bcma/scan.c index e19e987bc9e1..f94cccccfa56 100644 --- a/trunk/drivers/bcma/scan.c +++ b/trunk/drivers/bcma/scan.c @@ -19,14 +19,7 @@ struct bcma_device_id_name { u16 id; const char *name; }; - -static const struct bcma_device_id_name bcma_arm_device_names[] = { - { BCMA_CORE_ARM_1176, "ARM 1176" }, - { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" }, - { BCMA_CORE_ARM_CM3, "ARM CM3" }, -}; - -static const struct bcma_device_id_name bcma_bcm_device_names[] = { +struct bcma_device_id_name bcma_device_names[] = { { BCMA_CORE_OOB_ROUTER, "OOB Router" }, { BCMA_CORE_INVALID, "Invalid" }, { BCMA_CORE_CHIPCOMMON, "ChipCommon" }, @@ -34,6 +27,7 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = { { BCMA_CORE_SRAM, "SRAM" }, { BCMA_CORE_SDRAM, "SDRAM" }, { BCMA_CORE_PCI, "PCI" }, + { BCMA_CORE_MIPS, "MIPS" }, { BCMA_CORE_ETHERNET, "Fast Ethernet" }, { BCMA_CORE_V90, "V90" }, { BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" }, @@ -50,6 +44,7 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = { { BCMA_CORE_PHY_A, "PHY A" }, { BCMA_CORE_PHY_B, "PHY B" }, { BCMA_CORE_PHY_G, "PHY G" }, + { BCMA_CORE_MIPS_3302, "MIPS 3302" }, { BCMA_CORE_USB11_HOST, "USB 1.1 Host" }, { BCMA_CORE_USB11_DEV, "USB 1.1 Device" }, { BCMA_CORE_USB20_HOST, "USB 2.0 Host" }, @@ -63,11 +58,15 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = { { BCMA_CORE_PHY_N, "PHY N" }, { BCMA_CORE_SRAM_CTL, "SRAM Controller" }, { BCMA_CORE_MINI_MACPHY, "Mini MACPHY" }, + { BCMA_CORE_ARM_1176, "ARM 1176" }, + { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" }, { BCMA_CORE_PHY_LP, "PHY LP" }, { BCMA_CORE_PMU, "PMU" }, { BCMA_CORE_PHY_SSN, "PHY SSN" }, { BCMA_CORE_SDIO_DEV, "SDIO Device" }, + { BCMA_CORE_ARM_CM3, "ARM CM3" }, { BCMA_CORE_PHY_HT, "PHY HT" }, + { BCMA_CORE_MIPS_74K, "MIPS 74K" }, { BCMA_CORE_MAC_GBIT, "GBit MAC" }, { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" }, { BCMA_CORE_PCIE_RC, "PCIe Root Complex" }, @@ -80,41 +79,16 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = { { BCMA_CORE_SHIM, "SHIM" }, { BCMA_CORE_DEFAULT, "Default" }, }; - -static const struct bcma_device_id_name bcma_mips_device_names[] = { - { BCMA_CORE_MIPS, "MIPS" }, - { BCMA_CORE_MIPS_3302, "MIPS 3302" }, - { BCMA_CORE_MIPS_74K, "MIPS 74K" }, -}; - -static const char *bcma_device_name(const struct bcma_device_id *id) +const char *bcma_device_name(struct bcma_device_id *id) { - const struct bcma_device_id_name *names; - int size, i; - - /* search manufacturer specific names */ - switch (id->manuf) { - case BCMA_MANUF_ARM: - names = bcma_arm_device_names; - size = ARRAY_SIZE(bcma_arm_device_names); - break; - case BCMA_MANUF_BCM: - names = bcma_bcm_device_names; - size = ARRAY_SIZE(bcma_bcm_device_names); - break; - case BCMA_MANUF_MIPS: - names = bcma_mips_device_names; - size = ARRAY_SIZE(bcma_mips_device_names); - break; - default: - return "UNKNOWN"; - } + int i; - for (i = 0; i < size; i++) { - if (names[i].id == id->id) - return names[i].name; + if (id->manuf == BCMA_MANUF_BCM) { + for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) { + if (bcma_device_names[i].id == id->id) + return bcma_device_names[i].name; + } } - return "UNKNOWN"; } diff --git a/trunk/drivers/bcma/sprom.c b/trunk/drivers/bcma/sprom.c index c7f93359acb0..3e2a6002aae6 100644 --- a/trunk/drivers/bcma/sprom.c +++ b/trunk/drivers/bcma/sprom.c @@ -181,22 +181,6 @@ static int bcma_sprom_valid(const u16 *sprom) #define SPEX(_field, _offset, _mask, _shift) \ bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift)) -#define SPEX32(_field, _offset, _mask, _shift) \ - bus->sprom._field = ((((u32)sprom[SPOFF((_offset)+2)] << 16 | \ - sprom[SPOFF(_offset)]) & (_mask)) >> (_shift)) - -#define SPEX_ARRAY8(_field, _offset, _mask, _shift) \ - do { \ - SPEX(_field[0], _offset + 0, _mask, _shift); \ - SPEX(_field[1], _offset + 2, _mask, _shift); \ - SPEX(_field[2], _offset + 4, _mask, _shift); \ - SPEX(_field[3], _offset + 6, _mask, _shift); \ - SPEX(_field[4], _offset + 8, _mask, _shift); \ - SPEX(_field[5], _offset + 10, _mask, _shift); \ - SPEX(_field[6], _offset + 12, _mask, _shift); \ - SPEX(_field[7], _offset + 14, _mask, _shift); \ - } while (0) - static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) { u16 v, o; @@ -259,8 +243,7 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0); SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0); - SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8); - SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0); + SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0); /* Extract cores power info info */ for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { @@ -315,136 +298,6 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) SSB_SROM8_FEM_TR_ISO_SHIFT); SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); - - SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A, - SSB_SPROM8_ANTAVAIL_A_SHIFT); - SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG, - SSB_SPROM8_ANTAVAIL_BG_SHIFT); - SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0); - SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG, - SSB_SPROM8_ITSSI_BG_SHIFT); - SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0); - SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A, - SSB_SPROM8_ITSSI_A_SHIFT); - SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0); - SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK, - SSB_SPROM8_MAXP_AL_SHIFT); - SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0); - SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1, - SSB_SPROM8_GPIOA_P1_SHIFT); - SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0); - SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3, - SSB_SPROM8_GPIOB_P3_SHIFT); - SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0); - SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G, - SSB_SPROM8_TRI5G_SHIFT); - SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0); - SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH, - SSB_SPROM8_TRI5GH_SHIFT); - SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, - SSB_SPROM8_RXPO2G_SHIFT); - SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G, - SSB_SPROM8_RXPO5G_SHIFT); - SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0); - SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G, - SSB_SPROM8_RSSISMC2G_SHIFT); - SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G, - SSB_SPROM8_RSSISAV2G_SHIFT); - SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G, - SSB_SPROM8_BXA2G_SHIFT); - SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0); - SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G, - SSB_SPROM8_RSSISMC5G_SHIFT); - SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G, - SSB_SPROM8_RSSISAV5G_SHIFT); - SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G, - SSB_SPROM8_BXA5G_SHIFT); - - SPEX(pa0b0, SSB_SPROM8_PA0B0, ~0, 0); - SPEX(pa0b1, SSB_SPROM8_PA0B1, ~0, 0); - SPEX(pa0b2, SSB_SPROM8_PA0B2, ~0, 0); - SPEX(pa1b0, SSB_SPROM8_PA1B0, ~0, 0); - SPEX(pa1b1, SSB_SPROM8_PA1B1, ~0, 0); - SPEX(pa1b2, SSB_SPROM8_PA1B2, ~0, 0); - SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, ~0, 0); - SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, ~0, 0); - SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, ~0, 0); - SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, ~0, 0); - SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, ~0, 0); - SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, ~0, 0); - SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, ~0, 0); - SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, ~0, 0); - SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, ~0, 0); - SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, ~0, 0); - SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0); - - /* Extract the antenna gain values. */ - SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01, - SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT); - SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01, - SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT); - SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23, - SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT); - SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23, - SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT); - - SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON, - SSB_SPROM8_LEDDC_ON_SHIFT); - SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF, - SSB_SPROM8_LEDDC_OFF_SHIFT); - - SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN, - SSB_SPROM8_TXRXC_TXCHAIN_SHIFT); - SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN, - SSB_SPROM8_TXRXC_RXCHAIN_SHIFT); - SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH, - SSB_SPROM8_TXRXC_SWITCH_SHIFT); - - SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0); - - SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0); - SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0); - SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0); - SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0); - - SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP, - SSB_SPROM8_RAWTS_RAWTEMP_SHIFT); - SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER, - SSB_SPROM8_RAWTS_MEASPOWER_SHIFT); - SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX, - SSB_SPROM8_OPT_CORRX_TEMP_SLOPE, - SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT); - SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX, - SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT); - SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX, - SSB_SPROM8_OPT_CORRX_TEMP_OPTION, - SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT); - SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP, - SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR, - SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT); - SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP, - SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP, - SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT); - SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL, - SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT); - - SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0); - SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0); - SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0); - SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0); - - SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH, - SSB_SPROM8_THERMAL_TRESH_SHIFT); - SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET, - SSB_SPROM8_THERMAL_OFFSET_SHIFT); - SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA, - SSB_SPROM8_TEMPDELTA_PHYCAL, - SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT); - SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD, - SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT); - SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA, - SSB_SPROM8_TEMPDELTA_HYSTERESIS, - SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT); } /* diff --git a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c index b869a358ce43..28a65d3a03d0 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -693,8 +693,8 @@ ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, ie, 2 + vif->ssid_len + beacon_ie_len, 0, GFP_KERNEL); if (bss) - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, - "added bss %pM to cfg80211\n", bssid); + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added bss %pM to " + "cfg80211\n", bssid); kfree(ie); } else ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n"); @@ -882,32 +882,6 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, vif->sme_state = SME_DISCONNECTED; } -static int ath6kl_set_probed_ssids(struct ath6kl *ar, - struct ath6kl_vif *vif, - struct cfg80211_ssid *ssids, int n_ssids) -{ - u8 i; - - if (n_ssids > MAX_PROBED_SSID_INDEX) - return -EINVAL; - - for (i = 0; i < n_ssids; i++) { - ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, - ssids[i].ssid_len ? - SPECIFIC_SSID_FLAG : ANY_SSID_FLAG, - ssids[i].ssid_len, - ssids[i].ssid); - } - - /* Make sure no old entries are left behind */ - for (i = n_ssids; i < MAX_PROBED_SSID_INDEX; i++) { - ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, - DISABLE_SSID_FLAG, 0, NULL); - } - - return 0; -} - static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_scan_request *request) { @@ -925,25 +899,36 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, if (!ar->usr_bss_filter) { clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); - ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, - ALL_BSS_FILTER, 0); + ret = ath6kl_wmi_bssfilter_cmd( + ar->wmi, vif->fw_vif_idx, + (test_bit(CONNECTED, &vif->flags) ? + ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0); if (ret) { ath6kl_err("couldn't set bss filtering\n"); return ret; } } - ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, - request->n_ssids); - if (ret < 0) - return ret; + if (request->n_ssids && request->ssids[0].ssid_len) { + u8 i; + + if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) + request->n_ssids = MAX_PROBED_SSID_INDEX - 1; + + for (i = 0; i < request->n_ssids; i++) + ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, + i + 1, SPECIFIC_SSID_FLAG, + request->ssids[i].ssid_len, + request->ssids[i].ssid); + } /* this also clears IE in fw if it's not set */ ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, WMI_FRAME_PROBE_REQ, request->ie, request->ie_len); if (ret) { - ath6kl_err("failed to set Probe Request appie for scan"); + ath6kl_err("failed to set Probe Request appie for " + "scan"); return ret; } @@ -960,7 +945,8 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL); if (channels == NULL) { - ath6kl_warn("failed to set scan channels, scan all channels"); + ath6kl_warn("failed to set scan channels, " + "scan all channels"); n_channels = 0; } @@ -1032,20 +1018,6 @@ void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted) vif->scan_req = NULL; } -void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, - enum wmi_phy_mode mode) -{ - enum nl80211_channel_type type; - - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, - "channel switch notify nw_type %d freq %d mode %d\n", - vif->nw_type, freq, mode); - - type = (mode == WMI_11G_HT20) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT; - - cfg80211_ch_switch_notify(vif->ndev, freq, type); -} - static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr, @@ -1139,8 +1111,9 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, ar->ap_mode_bkey.key_len = key->key_len; memcpy(ar->ap_mode_bkey.key, key->key, key->key_len); if (!test_bit(CONNECTED, &vif->flags)) { - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, - "Delay initial group key configuration until AP mode has been started\n"); + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group " + "key configuration until AP mode has been " + "started\n"); /* * The key will be set in ath6kl_connect_ap_mode() once * the connected event is received from the target. @@ -1156,8 +1129,8 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, * the AP mode has properly started * (ath6kl_install_statioc_wep_keys). */ - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, - "Delay WEP key configuration until AP mode has been started\n"); + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration " + "until AP mode has been started\n"); vif->wep_key_list[key_index].key_len = key->key_len; memcpy(vif->wep_key_list[key_index].key, key->key, key->key_len); @@ -1989,7 +1962,8 @@ static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif) sizeof(discvr_pattern), discvr_offset, discvr_pattern, discvr_mask); if (ret) { - ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n"); + ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR " + "pattern\n"); return ret; } } @@ -2057,10 +2031,6 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) u8 index = 0; __be32 ips[MAX_IP_ADDRS]; - /* The FW currently can't support multi-vif WoW properly. */ - if (ar->num_vif > 1) - return -EIO; - vif = ath6kl_vif_first(ar); if (!vif) return -EIO; @@ -2074,13 +2044,6 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) return -EINVAL; - if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) { - ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, - vif->fw_vif_idx, false); - if (ret) - return ret; - } - /* Clear existing WOW patterns */ for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++) ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx, @@ -2184,8 +2147,8 @@ static int ath6kl_wow_resume(struct ath6kl *ar) ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_HOST_MODE_AWAKE); if (ret) { - ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n", - ret); + ath6kl_warn("Failed to configure host sleep mode for " + "wow resume: %d\n", ret); ar->state = ATH6KL_STATE_WOW; return ret; } @@ -2209,13 +2172,6 @@ static int ath6kl_wow_resume(struct ath6kl *ar) ar->state = ATH6KL_STATE_ON; - if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags)) { - ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, - vif->fw_vif_idx, true); - if (ret) - return ret; - } - netif_wake_queue(vif->ndev); return 0; @@ -2230,10 +2186,8 @@ static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar) if (!vif) return -EIO; - if (!test_bit(WMI_READY, &ar->flag)) { - ath6kl_err("deepsleep failed as wmi is not ready\n"); + if (!ath6kl_cfg80211_ready(vif)) return -EIO; - } ath6kl_cfg80211_stop_all(ar); @@ -2493,24 +2447,6 @@ static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band, band, htcap); } -static int ath6kl_restore_htcap(struct ath6kl_vif *vif) -{ - struct wiphy *wiphy = vif->ar->wiphy; - int band, ret = 0; - - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - if (!wiphy->bands[band]) - continue; - - ret = ath6kl_set_htcap(vif, band, - wiphy->bands[band]->ht_cap.ht_supported); - if (ret) - return ret; - } - - return ret; -} - static bool ath6kl_is_p2p_ie(const u8 *pos) { return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && @@ -2632,34 +2568,28 @@ static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon, /* skip element id and length */ rsn_ie += 2; - /* skip version */ - if (rsn_ie_len < 2) + /* skip version, group cipher */ + if (rsn_ie_len < 6) return -EINVAL; - rsn_ie += 2; - rsn_ie_len -= 2; - - /* skip group cipher suite */ - if (rsn_ie_len < 4) - return 0; - rsn_ie += 4; - rsn_ie_len -= 4; + rsn_ie += 6; + rsn_ie_len -= 6; /* skip pairwise cipher suite */ if (rsn_ie_len < 2) - return 0; - cnt = get_unaligned_le16(rsn_ie); + return -EINVAL; + cnt = *((u16 *) rsn_ie); rsn_ie += (2 + cnt * 4); rsn_ie_len -= (2 + cnt * 4); /* skip akm suite */ if (rsn_ie_len < 2) - return 0; - cnt = get_unaligned_le16(rsn_ie); + return -EINVAL; + cnt = *((u16 *) rsn_ie); rsn_ie += (2 + cnt * 4); rsn_ie_len -= (2 + cnt * 4); if (rsn_ie_len < 2) - return 0; + return -EINVAL; memcpy(rsn_capab, rsn_ie, 2); @@ -2836,7 +2766,6 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, return res; } - memcpy(&vif->profile, &p, sizeof(p)); res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p); if (res < 0) return res; @@ -2872,7 +2801,13 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev) clear_bit(CONNECTED, &vif->flags); /* Restore ht setting in firmware */ - return ath6kl_restore_htcap(vif); + if (ath6kl_set_htcap(vif, IEEE80211_BAND_2GHZ, true)) + return -EIO; + + if (ath6kl_set_htcap(vif, IEEE80211_BAND_5GHZ, true)) + return -EIO; + + return 0; } static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -3146,6 +3081,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, struct ath6kl_vif *vif = netdev_priv(dev); u16 interval; int ret; + u8 i; if (ar->state != ATH6KL_STATE_ON) return -EIO; @@ -3153,23 +3089,29 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, if (vif->sme_state != SME_DISCONNECTED) return -EBUSY; - /* The FW currently can't support multi-vif WoW properly. */ - if (ar->num_vif > 1) - return -EIO; - ath6kl_cfg80211_scan_complete_event(vif, true); - ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, - request->n_ssids); - if (ret < 0) - return ret; + for (i = 0; i < ar->wiphy->max_sched_scan_ssids; i++) { + ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, + i, DISABLE_SSID_FLAG, + 0, NULL); + } /* fw uses seconds, also make sure that it's >0 */ interval = max_t(u16, 1, request->interval / 1000); ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, interval, interval, - vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0); + 10, 0, 0, 0, 3, 0, 0, 0); + + if (request->n_ssids && request->ssids[0].ssid_len) { + for (i = 0; i < request->n_ssids; i++) { + ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, + i, SPECIFIC_SSID_FLAG, + request->ssids[i].ssid_len, + request->ssids[i].ssid); + } + } ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_WOW_MODE_ENABLE, @@ -3329,7 +3271,8 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0) - ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n"); + ath6kl_warn("ath6kl_deep_sleep_enable: " + "wmi_powermode_cmd failed\n"); return; } @@ -3409,7 +3352,6 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, vif->next_mode = nw_type; vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL; vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME; - vif->bg_scan_period = 0; vif->htcap.ht_enable = true; memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); @@ -3451,7 +3393,6 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, int ath6kl_cfg80211_init(struct ath6kl *ar) { struct wiphy *wiphy = ar->wiphy; - bool band_2gig = false, band_5gig = false, ht = false; int ret; wiphy->mgmt_stypes = ath6kl_mgmt_stypes; @@ -3472,46 +3413,8 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) /* max num of ssids that can be probed during scanning */ wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ - switch (ar->hw.cap) { - case WMI_11AN_CAP: - ht = true; - case WMI_11A_CAP: - band_5gig = true; - break; - case WMI_11GN_CAP: - ht = true; - case WMI_11G_CAP: - band_2gig = true; - break; - case WMI_11AGN_CAP: - ht = true; - case WMI_11AG_CAP: - band_2gig = true; - band_5gig = true; - break; - default: - ath6kl_err("invalid phy capability!\n"); - return -EINVAL; - } - - /* - * Even if the fw has HT support, advertise HT cap only when - * the firmware has support to override RSN capability, otherwise - * 4-way handshake would fail. - */ - if (!(ht && - test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, - ar->fw_capabilities))) { - ath6kl_band_2ghz.ht_cap.cap = 0; - ath6kl_band_2ghz.ht_cap.ht_supported = false; - ath6kl_band_5ghz.ht_cap.cap = 0; - ath6kl_band_5ghz.ht_cap.ht_supported = false; - } - if (band_2gig) - wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; - if (band_5gig) - wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; - + wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; + wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; wiphy->cipher_suites = cipher_suites; @@ -3527,7 +3430,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) wiphy->wowlan.pattern_min_len = 1; wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; - wiphy->max_sched_scan_ssids = MAX_PROBED_SSID_INDEX; + wiphy->max_sched_scan_ssids = 10; ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | WIPHY_FLAG_HAVE_AP_SME | @@ -3544,7 +3447,8 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) ar->wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; ret = wiphy_register(wiphy); if (ret < 0) { diff --git a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h index 5ea8cbb79f43..c5def436417f 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -28,8 +28,6 @@ enum ath6kl_cfg_suspend_mode { struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, enum nl80211_iftype type, u8 fw_vif_idx, u8 nw_type); -void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, - enum wmi_phy_mode mode); void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, diff --git a/trunk/drivers/net/wireless/ath/ath6kl/core.h b/trunk/drivers/net/wireless/ath/ath6kl/core.h index 4d9c6f142698..9d67964a51dd 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/core.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/core.h @@ -126,9 +126,9 @@ struct ath6kl_fw_ie { #define AR6003_HW_2_0_FIRMWARE_FILE "athwlan.bin.z77" #define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" #define AR6003_HW_2_0_PATCH_FILE "data.patch.bin" -#define AR6003_HW_2_0_BOARD_DATA_FILE AR6003_HW_2_0_FW_DIR "/bdata.bin" +#define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin" #define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \ - AR6003_HW_2_0_FW_DIR "/bdata.SD31.bin" + "ath6k/AR6003/hw2.0/bdata.SD31.bin" /* AR6003 3.0 definitions */ #define AR6003_HW_2_1_1_VERSION 0x30000582 @@ -139,33 +139,25 @@ struct ath6kl_fw_ie { #define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE "utf.bin" #define AR6003_HW_2_1_1_TESTSCRIPT_FILE "nullTestFlow.bin" #define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin" -#define AR6003_HW_2_1_1_BOARD_DATA_FILE AR6003_HW_2_1_1_FW_DIR "/bdata.bin" +#define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" #define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \ - AR6003_HW_2_1_1_FW_DIR "/bdata.SD31.bin" + "ath6k/AR6003/hw2.1.1/bdata.SD31.bin" /* AR6004 1.0 definitions */ #define AR6004_HW_1_0_VERSION 0x30000623 #define AR6004_HW_1_0_FW_DIR "ath6k/AR6004/hw1.0" #define AR6004_HW_1_0_FIRMWARE_FILE "fw.ram.bin" -#define AR6004_HW_1_0_BOARD_DATA_FILE AR6004_HW_1_0_FW_DIR "/bdata.bin" +#define AR6004_HW_1_0_BOARD_DATA_FILE "ath6k/AR6004/hw1.0/bdata.bin" #define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \ - AR6004_HW_1_0_FW_DIR "/bdata.DB132.bin" + "ath6k/AR6004/hw1.0/bdata.DB132.bin" /* AR6004 1.1 definitions */ #define AR6004_HW_1_1_VERSION 0x30000001 #define AR6004_HW_1_1_FW_DIR "ath6k/AR6004/hw1.1" #define AR6004_HW_1_1_FIRMWARE_FILE "fw.ram.bin" -#define AR6004_HW_1_1_BOARD_DATA_FILE AR6004_HW_1_1_FW_DIR "/bdata.bin" +#define AR6004_HW_1_1_BOARD_DATA_FILE "ath6k/AR6004/hw1.1/bdata.bin" #define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \ - AR6004_HW_1_1_FW_DIR "/bdata.DB132.bin" - -/* AR6004 1.2 definitions */ -#define AR6004_HW_1_2_VERSION 0x300007e8 -#define AR6004_HW_1_2_FW_DIR "ath6k/AR6004/hw1.2" -#define AR6004_HW_1_2_FIRMWARE_FILE "fw.ram.bin" -#define AR6004_HW_1_2_BOARD_DATA_FILE AR6004_HW_1_2_FW_DIR "/bdata.bin" -#define AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE \ - AR6004_HW_1_2_FW_DIR "/bdata.bin" + "ath6k/AR6004/hw1.1/bdata.DB132.bin" /* Per STA data, used in AP mode */ #define STA_PS_AWAKE BIT(0) @@ -510,8 +502,6 @@ enum ath6kl_vif_state { WLAN_ENABLED, STATS_UPDATE_PEND, HOST_SLEEP_MODE_CMD_PROCESSED, - NETDEV_MCAST_ALL_ON, - NETDEV_MCAST_ALL_OFF, }; struct ath6kl_vif { @@ -559,11 +549,9 @@ struct ath6kl_vif { u16 assoc_bss_beacon_int; u16 listen_intvl_t; u16 bmiss_time_t; - u16 bg_scan_period; u8 assoc_bss_dtim_period; struct net_device_stats net_stats; struct target_stats target_stats; - struct wmi_connect_cmd profile; struct list_head mc_filter; }; @@ -652,7 +640,6 @@ struct ath6kl { u8 sta_list_index; struct ath6kl_req_key ap_mode_bkey; struct sk_buff_head mcastpsq; - u32 want_ch_switch; /* * FIXME: protects access to mcastpsq but is actually useless as @@ -685,7 +672,6 @@ struct ath6kl { u32 refclk_hz; u32 uarttx_pin; u32 testscript_addr; - enum wmi_phy_cap cap; struct ath6kl_hw_fw { const char *dir; @@ -819,8 +805,7 @@ void aggr_reset_state(struct aggr_info_conn *aggr_conn); struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr); struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); -void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver, - enum wmi_phy_cap cap); +void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver); int ath6kl_control_tx(void *devt, struct sk_buff *skb, enum htc_endpoint_id eid); void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, diff --git a/trunk/drivers/net/wireless/ath/ath6kl/debug.c b/trunk/drivers/net/wireless/ath/ath6kl/debug.c index 15cfe30e54fd..1b76aff78508 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/debug.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/debug.c @@ -401,10 +401,8 @@ static ssize_t ath6kl_fwlog_block_read(struct file *file, ret = wait_for_completion_interruptible( &ar->debug.fwlog_completion); - if (ret == -ERESTARTSYS) { - vfree(buf); + if (ret == -ERESTARTSYS) return ret; - } spin_lock(&ar->debug.fwlog_queue.lock); } @@ -1572,15 +1570,10 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file, size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; - struct ath6kl_vif *vif; u16 bgscan_int; char buf[32]; ssize_t len; - vif = ath6kl_vif_first(ar); - if (!vif) - return -EIO; - len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) return -EFAULT; @@ -1592,8 +1585,6 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file, if (bgscan_int == 0) bgscan_int = 0xffff; - vif->bg_scan_period = bgscan_int; - ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3, 0, 0, 0); @@ -1818,7 +1809,6 @@ int ath6kl_debug_init_fs(struct ath6kl *ar) void ath6kl_debug_cleanup(struct ath6kl *ar) { skb_queue_purge(&ar->debug.fwlog_queue); - complete(&ar->debug.fwlog_completion); kfree(ar->debug.roam_tbl); } diff --git a/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c index 2798624d3a9d..065e61516d7a 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c @@ -83,7 +83,10 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info, * never goes inactive EVER. */ cur_ep_dist->dist_flags |= HTC_EP_ACTIVE; - } + } else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC) + /* this is the lowest priority data endpoint */ + /* FIXME: this looks fishy, check */ + cred_info->lowestpri_ep_dist = cur_ep_dist->list; /* * Streams have to be created (explicit | implicit) for all @@ -97,13 +100,6 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info, */ } - /* - * For ath6kl_credit_seek function, - * it use list_for_each_entry_reverse to walk around the whole ep list. - * Therefore assign this lowestpri_ep_dist after walk around the ep_list - */ - cred_info->lowestpri_ep_dist = cur_ep_dist->list; - WARN_ON(cred_info->cur_free_credits <= 0); list_for_each_entry(cur_ep_dist, ep_list, list) { @@ -762,7 +758,7 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, u32 txb_mask; u8 ac = WMM_NUM_AC; - if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) && + if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || (WMI_CONTROL_SVC != endpoint->svc_id)) ac = target->dev->ar->ep2ac_map[endpoint->eid]; @@ -797,17 +793,16 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, * itself */ txb_mask = ((1 << ac) - 1); - - /* - * when the scatter request resources drop below a - * certain threshold, disable Tx bundling for all - * AC's with priority lower than the current requesting - * AC. Otherwise re-enable Tx bundling for them - */ - if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS) - target->tx_bndl_mask &= ~txb_mask; - else - target->tx_bndl_mask |= txb_mask; + /* + * when the scatter request resources drop below a + * certain threshold, disable Tx bundling for all + * AC's with priority lower than the current requesting + * AC. Otherwise re-enable Tx bundling for them + */ + if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS) + target->tx_bndl_mask &= ~txb_mask; + else + target->tx_bndl_mask |= txb_mask; } ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", @@ -854,7 +849,6 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, int bundle_sent; int n_pkts_bundle; u8 ac = WMM_NUM_AC; - int status; spin_lock_bh(&target->tx_lock); @@ -872,7 +866,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, */ INIT_LIST_HEAD(&txq); - if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) && + if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || (WMI_CONTROL_SVC != endpoint->svc_id)) ac = target->dev->ar->ep2ac_map[endpoint->eid]; @@ -916,12 +910,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags, 0, packet->info.tx.seqno); - status = ath6kl_htc_tx_issue(target, packet); - - if (status) { - packet->status = status; - packet->completion(packet->context, packet); - } + ath6kl_htc_tx_issue(target, packet); } spin_lock_bh(&target->tx_lock); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c index f9626c723693..b277b3446882 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c @@ -108,6 +108,8 @@ static void get_htc_packet_credit_based(struct htc_target *target, /* get packet at head, but don't remove it */ packet = list_first_entry(&ep->txq, struct htc_packet, list); + if (packet == NULL) + break; ath6kl_dbg(ATH6KL_DBG_HTC, "%s: got head packet:0x%p , queue depth: %d\n", @@ -801,6 +803,8 @@ static int htc_send_packets_multiple(struct htc_target *target, /* get first packet to find out which ep the packets will go into */ packet = list_first_entry(pkt_queue, struct htc_packet, list); + if (packet == NULL) + return -EINVAL; if (packet->endpoint >= ENDPOINT_MAX) { WARN_ON_ONCE(1); @@ -1378,9 +1382,6 @@ static int ath6kl_htc_pipe_conn_service(struct htc_target *target, /* copy all the callbacks */ ep->ep_cb = conn_req->ep_cb; - /* initialize tx_drop_packet_threshold */ - ep->tx_drop_packet_threshold = MAX_HI_COOKIE_NUM; - status = ath6kl_hif_pipe_map_service(ar, ep->svc_id, &ep->pipe.pipeid_ul, &ep->pipe.pipeid_dl); @@ -1635,6 +1636,10 @@ static int ath6kl_htc_pipe_add_rxbuf_multiple(struct htc_target *target, return -EINVAL; first = list_first_entry(pkt_queue, struct htc_packet, list); + if (first == NULL) { + WARN_ON_ONCE(1); + return -EINVAL; + } if (first->endpoint >= ENDPOINT_MAX) { WARN_ON_ONCE(1); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/init.c b/trunk/drivers/net/wireless/ath/ath6kl/init.c index 7eb0515f458a..29ef50ea07d5 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/init.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/init.c @@ -119,24 +119,6 @@ static const struct ath6kl_hw hw_list[] = { .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE, .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE, }, - { - .id = AR6004_HW_1_2_VERSION, - .name = "ar6004 hw 1.2", - .dataset_patch_addr = 0x436ecc, - .app_load_addr = 0x1234, - .board_ext_data_addr = 0x437000, - .reserved_ram_size = 9216, - .board_addr = 0x435c00, - .refclk_hz = 40000000, - .uarttx_pin = 11, - - .fw = { - .dir = AR6004_HW_1_2_FW_DIR, - .fw = AR6004_HW_1_2_FIRMWARE_FILE, - }, - .fw_board = AR6004_HW_1_2_BOARD_DATA_FILE, - .fw_default_board = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE, - }, }; /* @@ -463,9 +445,9 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) P2P_FLAG_MACADDR_REQ | P2P_FLAG_HMODEL_REQ); if (ret) { - ath6kl_dbg(ATH6KL_DBG_TRC, - "failed to request P2P capabilities (%d) - assuming P2P not supported\n", - ret); + ath6kl_dbg(ATH6KL_DBG_TRC, "failed to request P2P " + "capabilities (%d) - assuming P2P not " + "supported\n", ret); ar->p2p = false; } } @@ -474,9 +456,8 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) /* Enable Probe Request reporting for P2P */ ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true); if (ret) { - ath6kl_dbg(ATH6KL_DBG_TRC, - "failed to enable Probe Request reporting (%d)\n", - ret); + ath6kl_dbg(ATH6KL_DBG_TRC, "failed to enable Probe " + "Request reporting (%d)\n", ret); } } diff --git a/trunk/drivers/net/wireless/ath/ath6kl/main.c b/trunk/drivers/net/wireless/ath/ath6kl/main.c index e5524470529c..4d818f96c415 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/main.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/main.c @@ -421,8 +421,8 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) if (!ik->valid) break; - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, - "Delayed addkey for the initial group key for AP mode\n"); + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed addkey for " + "the initial group key for AP mode\n"); memset(key_rsc, 0, sizeof(key_rsc)); res = ath6kl_wmi_addkey_cmd( ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type, @@ -430,19 +430,12 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) ik->key, KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG); if (res) { - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, - "Delayed addkey failed: %d\n", res); + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed " + "addkey failed: %d\n", res); } break; } - if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) { - ar->want_ch_switch &= ~(1 << vif->fw_vif_idx); - /* we actually don't know the phymode, default to HT20 */ - ath6kl_cfg80211_ch_switch_notify(vif, channel, - WMI_11G_HT20); - } - ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); set_bit(CONNECTED, &vif->flags); netif_carrier_on(vif->ndev); @@ -548,8 +541,7 @@ void ath6kl_disconnect(struct ath6kl_vif *vif) /* WMI Event handlers */ -void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver, - enum wmi_phy_cap cap) +void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver) { struct ath6kl *ar = devt; @@ -559,7 +551,6 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver, ar->version.wlan_ver = sw_ver; ar->version.abi_ver = abi_ver; - ar->hw.cap = cap; snprintf(ar->wiphy->fw_version, sizeof(ar->wiphy->fw_version), @@ -593,45 +584,6 @@ void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status) ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status); } -static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel) -{ - - struct ath6kl *ar = vif->ar; - - vif->next_chan = channel; - vif->profile.ch = cpu_to_le16(channel); - - switch (vif->nw_type) { - case AP_NETWORK: - return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, - &vif->profile); - default: - ath6kl_err("won't switch channels nw_type=%d\n", vif->nw_type); - return -ENOTSUPP; - } -} - -static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel) -{ - - struct ath6kl_vif *vif; - int res = 0; - - if (!ar->want_ch_switch) - return; - - spin_lock_bh(&ar->list_lock); - list_for_each_entry(vif, &ar->vif_list, list) { - if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) - res = ath6kl_commit_ch_switch(vif, channel); - - if (res) - ath6kl_err("channel switch failed nw_type %d res %d\n", - vif->nw_type, res); - } - spin_unlock_bh(&ar->list_lock); -} - void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, u16 listen_int, u16 beacon_int, enum network_type net_type, u8 beacon_ie_len, @@ -649,11 +601,9 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, memcpy(vif->bssid, bssid, sizeof(vif->bssid)); vif->bss_ch = channel; - if ((vif->nw_type == INFRA_NETWORK)) { + if ((vif->nw_type == INFRA_NETWORK)) ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, vif->listen_intvl_t, 0); - ath6kl_check_ch_switch(ar, channel); - } netif_wake_queue(vif->ndev); @@ -976,11 +926,6 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, struct ath6kl *ar = vif->ar; if (vif->nw_type == AP_NETWORK) { - /* disconnect due to other STA vif switching channels */ - if (reason == BSS_DISCONNECTED && - prot_reason_status == WMI_AP_REASON_STA_ROAM) - ar->want_ch_switch |= 1 << vif->fw_vif_idx; - if (!ath6kl_remove_sta(ar, bssid, prot_reason_status)) return; @@ -1145,7 +1090,7 @@ static int ath6kl_set_features(struct net_device *dev, static void ath6kl_set_multicast_list(struct net_device *ndev) { struct ath6kl_vif *vif = netdev_priv(ndev); - bool mc_all_on = false; + bool mc_all_on = false, mc_all_off = false; int mc_count = netdev_mc_count(ndev); struct netdev_hw_addr *ha; bool found; @@ -1157,41 +1102,24 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) !test_bit(WLAN_ENABLED, &vif->flags)) return; - /* Enable multicast-all filter. */ mc_all_on = !!(ndev->flags & IFF_PROMISC) || !!(ndev->flags & IFF_ALLMULTI) || !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST); - if (mc_all_on) - set_bit(NETDEV_MCAST_ALL_ON, &vif->flags); - else - clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags); - - mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON); + mc_all_off = !(ndev->flags & IFF_MULTICAST) || mc_count == 0; - if (!(ndev->flags & IFF_MULTICAST)) { - mc_all_on = false; - set_bit(NETDEV_MCAST_ALL_OFF, &vif->flags); - } else { - clear_bit(NETDEV_MCAST_ALL_OFF, &vif->flags); - } - - /* Enable/disable "multicast-all" filter*/ - ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast-all filter\n", - mc_all_on ? "enabling" : "disabling"); - - ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, + if (mc_all_on || mc_all_off) { + /* Enable/disable all multicast */ + ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n", + mc_all_on ? "enabling" : "disabling"); + ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, mc_all_on); - if (ret) { - ath6kl_warn("Failed to %s multicast-all receive\n", - mc_all_on ? "enable" : "disable"); + if (ret) + ath6kl_warn("Failed to %s multicast receive\n", + mc_all_on ? "enable" : "disable"); return; } - if (test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) - return; - - /* Keep the driver and firmware mcast list in sync. */ list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) { found = false; netdev_for_each_mc_addr(ha, ndev) { diff --git a/trunk/drivers/net/wireless/ath/ath6kl/sdio.c b/trunk/drivers/net/wireless/ath/ath6kl/sdio.c index 05b95405f7b5..44ea7a742101 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/sdio.c @@ -552,7 +552,7 @@ static int ath6kl_sdio_write_async(struct ath6kl *ar, u32 address, u8 *buffer, bus_req = ath6kl_sdio_alloc_busreq(ar_sdio); - if (WARN_ON_ONCE(!bus_req)) + if (!bus_req) return -ENOMEM; bus_req->address = address; @@ -915,9 +915,6 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) } cut_pwr: - if (func->card && func->card->host) - func->card->host->pm_flags &= ~MMC_PM_KEEP_POWER; - return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL); } @@ -988,8 +985,9 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr) } if (status) { - ath6kl_err("%s: failed to write initial bytes of 0x%x to window reg: 0x%X\n", - __func__, addr, reg_addr); + ath6kl_err("%s: failed to write initial bytes of 0x%x " + "to window reg: 0x%X\n", __func__, + addr, reg_addr); return status; } @@ -1078,8 +1076,8 @@ static int ath6kl_sdio_bmi_credits(struct ath6kl *ar) (u8 *)&ar->bmi.cmd_credits, 4, HIF_RD_SYNC_BYTE_INC); if (ret) { - ath6kl_err("Unable to decrement the command credit count register: %d\n", - ret); + ath6kl_err("Unable to decrement the command credit " + "count register: %d\n", ret); return ret; } @@ -1459,6 +1457,3 @@ MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_2_FW_DIR "/" AR6004_HW_1_2_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c index 67206aedea6c..82f2f5cb475b 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c @@ -362,11 +362,15 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) skb, skb->data, skb->len); /* If target is not associated */ - if (!test_bit(CONNECTED, &vif->flags)) - goto fail_tx; + if (!test_bit(CONNECTED, &vif->flags)) { + dev_kfree_skb(skb); + return 0; + } - if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) - goto fail_tx; + if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) { + dev_kfree_skb(skb); + return 0; + } if (!test_bit(WMI_READY, &ar->flag)) goto fail_tx; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/usb.c b/trunk/drivers/net/wireless/ath/ath6kl/usb.c index dfbbe9e7ff75..ec7f1f5fd1ca 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/usb.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/usb.c @@ -1037,14 +1037,6 @@ static void ath6kl_usb_stop(struct ath6kl *ar) hif_stop(ar); } -static void ath6kl_usb_cleanup_scatter(struct ath6kl *ar) -{ - /* - * USB doesn't support it. Just return. - */ - return; -} - static const struct ath6kl_hif_ops ath6kl_usb_ops = { .diag_read32 = ath6kl_usb_diag_read32, .diag_write32 = ath6kl_usb_diag_write32, @@ -1057,7 +1049,6 @@ static const struct ath6kl_hif_ops ath6kl_usb_ops = { .pipe_get_default = ath6kl_usb_get_default_pipe, .pipe_map_service = ath6kl_usb_map_service_pipe, .pipe_get_free_queue_number = ath6kl_usb_get_free_queue_number, - .cleanup_scatter = ath6kl_usb_cleanup_scatter, }; /* ath6kl usb driver registered functions */ @@ -1216,6 +1207,3 @@ MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_2_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c b/trunk/drivers/net/wireless/ath/ath6kl/wmi.c index ee8ec2394c2c..7c8a9977faf5 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/wmi.c @@ -16,7 +16,6 @@ */ #include -#include #include "core.h" #include "debug.h" #include "testmode.h" @@ -290,13 +289,6 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx, layer2_priority); } else usr_pri = layer2_priority & 0x7; - - /* - * Queue the EAPOL frames in the same WMM_AC_VO queue - * as that of management frames. - */ - if (skb->protocol == cpu_to_be16(ETH_P_PAE)) - usr_pri = WMI_VOICE_USER_PRIORITY; } /* @@ -468,9 +460,8 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap, freq, dur); chan = ieee80211_get_channel(ar->wiphy, freq); if (!chan) { - ath6kl_dbg(ATH6KL_DBG_WMI, - "remain_on_chnl: Unknown channel (freq=%u)\n", - freq); + ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: Unknown channel " + "(freq=%u)\n", freq); return -EINVAL; } id = vif->last_roc_id; @@ -497,14 +488,12 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi, ev = (struct wmi_cancel_remain_on_chnl_event *) datap; freq = le32_to_cpu(ev->freq); dur = le32_to_cpu(ev->duration); - ath6kl_dbg(ATH6KL_DBG_WMI, - "cancel_remain_on_chnl: freq=%u dur=%u status=%u\n", - freq, dur, ev->status); + ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: freq=%u dur=%u " + "status=%u\n", freq, dur, ev->status); chan = ieee80211_get_channel(ar->wiphy, freq); if (!chan) { - ath6kl_dbg(ATH6KL_DBG_WMI, - "cancel_remain_on_chnl: Unknown channel (freq=%u)\n", - freq); + ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: Unknown " + "channel (freq=%u)\n", freq); return -EINVAL; } if (vif->last_cancel_roc_id && @@ -559,12 +548,12 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len, freq = le32_to_cpu(ev->freq); dlen = le16_to_cpu(ev->len); if (datap + len < ev->data + dlen) { - ath6kl_err("invalid wmi_p2p_rx_probe_req_event: len=%d dlen=%u\n", - len, dlen); + ath6kl_err("invalid wmi_p2p_rx_probe_req_event: " + "len=%d dlen=%u\n", len, dlen); return -EINVAL; } - ath6kl_dbg(ATH6KL_DBG_WMI, - "rx_probe_req: len=%u freq=%u probe_req_report=%d\n", + ath6kl_dbg(ATH6KL_DBG_WMI, "rx_probe_req: len=%u freq=%u " + "probe_req_report=%d\n", dlen, freq, vif->probe_req_report); if (vif->probe_req_report || vif->nw_type == AP_NETWORK) @@ -603,8 +592,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len, freq = le32_to_cpu(ev->freq); dlen = le16_to_cpu(ev->len); if (datap + len < ev->data + dlen) { - ath6kl_err("invalid wmi_rx_action_event: len=%d dlen=%u\n", - len, dlen); + ath6kl_err("invalid wmi_rx_action_event: " + "len=%d dlen=%u\n", len, dlen); return -EINVAL; } ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); @@ -698,7 +687,7 @@ static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len) ath6kl_ready_event(wmi->parent_dev, ev->mac_addr, le32_to_cpu(ev->sw_version), - le32_to_cpu(ev->abi_version), ev->phy_cap); + le32_to_cpu(ev->abi_version)); return 0; } @@ -788,15 +777,16 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len, /* AP mode start/STA connected event */ struct net_device *dev = vif->ndev; if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) { - ath6kl_dbg(ATH6KL_DBG_WMI, - "%s: freq %d bssid %pM (AP started)\n", + ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM " + "(AP started)\n", __func__, le16_to_cpu(ev->u.ap_bss.ch), ev->u.ap_bss.bssid); ath6kl_connect_ap_mode_bss( vif, le16_to_cpu(ev->u.ap_bss.ch)); } else { - ath6kl_dbg(ATH6KL_DBG_WMI, - "%s: aid %u mac_addr %pM auth=%u keymgmt=%u cipher=%u apsd_info=%u (STA connected)\n", + ath6kl_dbg(ATH6KL_DBG_WMI, "%s: aid %u mac_addr %pM " + "auth=%u keymgmt=%u cipher=%u apsd_info=%u " + "(STA connected)\n", __func__, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr, ev->u.ap_sta.auth, @@ -1239,9 +1229,8 @@ static int ath6kl_wmi_neighbor_report_event_rx(struct wmi *wmi, u8 *datap, ev = (struct wmi_neighbor_report_event *) datap; if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info) > len) { - ath6kl_dbg(ATH6KL_DBG_WMI, - "truncated neighbor event (num=%d len=%d)\n", - ev->num_neighbors, len); + ath6kl_dbg(ATH6KL_DBG_WMI, "truncated neighbor event " + "(num=%d len=%d)\n", ev->num_neighbors, len); return -EINVAL; } for (i = 0; i < ev->num_neighbors; i++) { @@ -1825,14 +1814,12 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, u32 home_dwell_time, u32 force_scan_interval, s8 num_chan, u16 *ch_list, u32 no_cck, u32 *rates) { - struct ieee80211_supported_band *sband; struct sk_buff *skb; struct wmi_begin_scan_cmd *sc; - s8 size, *supp_rates; + s8 size; int i, band, ret; struct ath6kl *ar = wmi->parent_dev; int num_rates; - u32 ratemask; size = sizeof(struct wmi_begin_scan_cmd); @@ -1859,13 +1846,10 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, sc->num_ch = num_chan; for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - sband = ar->wiphy->bands[band]; - - if (!sband) - continue; - - ratemask = rates[band]; - supp_rates = sc->supp_rates[band].rates; + struct ieee80211_supported_band *sband = + ar->wiphy->bands[band]; + u32 ratemask = rates[band]; + u8 *supp_rates = sc->supp_rates[band].rates; num_rates = 0; for (i = 0; i < sband->n_bitrates; i++) { @@ -2145,8 +2129,8 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index, struct wmi_add_cipher_key_cmd *cmd; int ret; - ath6kl_dbg(ATH6KL_DBG_WMI, - "addkey cmd: key_index=%u key_type=%d key_usage=%d key_len=%d key_op_ctrl=%d\n", + ath6kl_dbg(ATH6KL_DBG_WMI, "addkey cmd: key_index=%u key_type=%d " + "key_usage=%d key_len=%d key_op_ctrl=%d\n", key_index, key_type, key_usage, key_len, key_op_ctrl); if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) || @@ -3063,8 +3047,8 @@ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, res = ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG); - ath6kl_dbg(ATH6KL_DBG_WMI, - "%s: nw_type=%u auth_mode=%u ch=%u ctrl_flags=0x%x-> res=%d\n", + ath6kl_dbg(ATH6KL_DBG_WMI, "%s: nw_type=%u auth_mode=%u ch=%u " + "ctrl_flags=0x%x-> res=%d\n", __func__, p->nw_type, p->auth_mode, le16_to_cpu(p->ch), le32_to_cpu(p->ctrl_flags), res); return res; @@ -3224,9 +3208,8 @@ int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, if (!skb) return -ENOMEM; - ath6kl_dbg(ATH6KL_DBG_WMI, - "set_appie_cmd: mgmt_frm_type=%u ie_len=%u\n", - mgmt_frm_type, ie_len); + ath6kl_dbg(ATH6KL_DBG_WMI, "set_appie_cmd: mgmt_frm_type=%u " + "ie_len=%u\n", mgmt_frm_type, ie_len); p = (struct wmi_set_appie_cmd *) skb->data; p->mgmt_frm_type = mgmt_frm_type; p->ie_len = ie_len; @@ -3327,9 +3310,8 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, wmi->last_mgmt_tx_frame = buf; wmi->last_mgmt_tx_frame_len = data_len; - ath6kl_dbg(ATH6KL_DBG_WMI, - "send_action_cmd: id=%u freq=%u wait=%u len=%u\n", - id, freq, wait, data_len); + ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u " + "len=%u\n", id, freq, wait, data_len); p = (struct wmi_send_action_cmd *) skb->data; p->id = cpu_to_le32(id); p->freq = cpu_to_le32(freq); @@ -3366,9 +3348,8 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, wmi->last_mgmt_tx_frame = buf; wmi->last_mgmt_tx_frame_len = data_len; - ath6kl_dbg(ATH6KL_DBG_WMI, - "send_action_cmd: id=%u freq=%u wait=%u len=%u\n", - id, freq, wait, data_len); + ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u " + "len=%u\n", id, freq, wait, data_len); p = (struct wmi_send_mgmt_cmd *) skb->data; p->id = cpu_to_le32(id); p->freq = cpu_to_le32(freq); @@ -3421,9 +3402,8 @@ int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, if (!skb) return -ENOMEM; - ath6kl_dbg(ATH6KL_DBG_WMI, - "send_probe_response_cmd: freq=%u dst=%pM len=%u\n", - freq, dst, data_len); + ath6kl_dbg(ATH6KL_DBG_WMI, "send_probe_response_cmd: freq=%u dst=%pM " + "len=%u\n", freq, dst, data_len); p = (struct wmi_p2p_probe_response_cmd *) skb->data; p->freq = cpu_to_le32(freq); memcpy(p->destination_addr, dst, ETH_ALEN); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h index 9076bec3a2ba..d3d2ab5c1689 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h @@ -106,8 +106,6 @@ struct wmi_data_sync_bufs { #define WMM_AC_VI 2 /* video */ #define WMM_AC_VO 3 /* voice */ -#define WMI_VOICE_USER_PRIORITY 0x7 - struct wmi { u16 stream_exist_for_ac[WMM_NUM_AC]; u8 fat_pipe_exist; @@ -1153,7 +1151,6 @@ enum wmi_phy_mode { WMI_11AG_MODE = 0x3, WMI_11B_MODE = 0x4, WMI_11GONLY_MODE = 0x5, - WMI_11G_HT20 = 0x6, }; #define WMI_MAX_CHANNELS 32 @@ -1419,16 +1416,6 @@ struct wmi_ready_event_2 { u8 phy_cap; } __packed; -/* WMI_PHY_CAPABILITY */ -enum wmi_phy_cap { - WMI_11A_CAP = 0x01, - WMI_11G_CAP = 0x02, - WMI_11AG_CAP = 0x03, - WMI_11AN_CAP = 0x04, - WMI_11GN_CAP = 0x05, - WMI_11AGN_CAP = 0x06, -}; - /* Connect Event */ struct wmi_connect_event { union { @@ -1481,17 +1468,6 @@ enum wmi_disconnect_reason { IBSS_MERGE = 0xe, }; -/* AP mode disconnect proto_reasons */ -enum ap_disconnect_reason { - WMI_AP_REASON_STA_LEFT = 101, - WMI_AP_REASON_FROM_HOST = 102, - WMI_AP_REASON_COMM_TIMEOUT = 103, - WMI_AP_REASON_MAX_STA = 104, - WMI_AP_REASON_ACL = 105, - WMI_AP_REASON_STA_ROAM = 106, - WMI_AP_REASON_DFS_CHANNEL = 107, -}; - #define ATH6KL_COUNTRY_RD_SHIFT 16 struct ath6kl_wmi_regdomain { diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 9fdd70fcaf5b..a0387a027db0 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -892,6 +892,34 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah) AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); } +static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan) +{ + struct ath9k_rtt_hist *hist; + u32 *table; + int i; + bool restore; + + if (!ah->caldata) + return false; + + hist = &ah->caldata->rtt_hist; + if (!hist->num_readings) + return false; + + ar9003_hw_rtt_enable(ah); + ar9003_hw_rtt_set_mask(ah, 0x00); + for (i = 0; i < AR9300_MAX_CHAINS; i++) { + if (!(ah->rxchainmask & (1 << i))) + continue; + table = &hist->table[i][hist->num_readings][0]; + ar9003_hw_rtt_load_hist(ah, i, table); + } + restore = ar9003_hw_rtt_force_restore(ah); + ar9003_hw_rtt_disable(ah); + + return restore; +} + static bool ar9003_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -914,10 +942,9 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, if (!ar9003_hw_rtt_restore(ah, chan)) run_rtt_cal = true; - if (run_rtt_cal) - ath_dbg(common, CALIBRATE, "RTT calibration to be done\n"); + ath_dbg(common, CALIBRATE, "RTT restore %s\n", + run_rtt_cal ? "failed" : "succeed"); } - run_agc_cal = run_rtt_cal; if (run_rtt_cal) { @@ -1042,14 +1069,17 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, #undef CL_TAB_ENTRY if (run_rtt_cal && caldata) { - if (is_reusable) { - if (!ath9k_hw_rfbus_req(ah)) - ath_err(ath9k_hw_common(ah), - "Could not stop baseband\n"); - else - ar9003_hw_rtt_fill_hist(ah); + struct ath9k_rtt_hist *hist = &caldata->rtt_hist; + if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) { + u32 *table; - ath9k_hw_rfbus_done(ah); + hist->num_readings++; + for (i = 0; i < AR9300_MAX_CHAINS; i++) { + if (!(ah->rxchainmask & (1 << i))) + continue; + table = &hist->table[i][hist->num_readings][0]; + ar9003_hw_rtt_fill_hist(ah, i, table); + } } ar9003_hw_rtt_disable(ah); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c index ffbb180f91e1..3cac293a2849 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -756,7 +756,7 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (caldata) { caldata->done_txiqcal_once = false; caldata->done_txclcal_once = false; - caldata->rtt_done = false; + caldata->rtt_hist.num_readings = 0; } if (!ath9k_hw_init_cal(ah, chan)) diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_rtt.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_rtt.c index 74de3539c2c8..458bedf0b0ae 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_rtt.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_rtt.c @@ -15,7 +15,6 @@ */ #include "hw.h" -#include "hw-ops.h" #include "ar9003_phy.h" #include "ar9003_rtt.h" @@ -70,7 +69,7 @@ bool ar9003_hw_rtt_force_restore(struct ath_hw *ah) } static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain, - u32 index, u32 data28) + u32 index, u32 data28) { u32 val; @@ -101,21 +100,12 @@ static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain, RTT_ACCESS_TIMEOUT); } -void ar9003_hw_rtt_load_hist(struct ath_hw *ah) +void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table) { - int chain, i; + int i; - for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { - if (!(ah->rxchainmask & (1 << chain))) - continue; - for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) { - ar9003_hw_rtt_load_hist_entry(ah, chain, i, - ah->caldata->rtt_table[chain][i]); - ath_dbg(ath9k_hw_common(ah), CALIBRATE, - "Load RTT value at idx %d, chain %d: 0x%x\n", - i, chain, ah->caldata->rtt_table[chain][i]); - } - } + for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) + ar9003_hw_rtt_load_hist_entry(ah, chain, i, table[i]); } static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index) @@ -138,71 +128,27 @@ static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index) RTT_ACCESS_TIMEOUT)) return RTT_BAD_VALUE; - val = MS(REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)), - AR_PHY_RTT_SW_RTT_TABLE_DATA); - + val = REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)); return val; } -void ar9003_hw_rtt_fill_hist(struct ath_hw *ah) +void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table) { - int chain, i; - - for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { - if (!(ah->rxchainmask & (1 << chain))) - continue; - for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) { - ah->caldata->rtt_table[chain][i] = - ar9003_hw_rtt_fill_hist_entry(ah, chain, i); - ath_dbg(ath9k_hw_common(ah), CALIBRATE, - "RTT value at idx %d, chain %d is: 0x%x\n", - i, chain, ah->caldata->rtt_table[chain][i]); - } - } + int i; - ah->caldata->rtt_done = true; + for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) + table[i] = ar9003_hw_rtt_fill_hist_entry(ah, chain, i); } void ar9003_hw_rtt_clear_hist(struct ath_hw *ah) { - int chain, i; + int i, j; - for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { - if (!(ah->rxchainmask & (1 << chain))) + for (i = 0; i < AR9300_MAX_CHAINS; i++) { + if (!(ah->rxchainmask & (1 << i))) continue; - for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) - ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0); + for (j = 0; j < MAX_RTT_TABLE_ENTRY; j++) + ar9003_hw_rtt_load_hist_entry(ah, i, j, 0); } - - if (ah->caldata) - ah->caldata->rtt_done = false; -} - -bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan) -{ - bool restore; - - if (!ah->caldata) - return false; - - if (!ah->caldata->rtt_done) - return false; - - ar9003_hw_rtt_enable(ah); - ar9003_hw_rtt_set_mask(ah, 0x10); - - if (!ath9k_hw_rfbus_req(ah)) { - ath_err(ath9k_hw_common(ah), "Could not stop baseband\n"); - restore = false; - goto fail; - } - - ar9003_hw_rtt_load_hist(ah); - restore = ar9003_hw_rtt_force_restore(ah); - -fail: - ath9k_hw_rfbus_done(ah); - ar9003_hw_rtt_disable(ah); - return restore; } diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_rtt.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_rtt.h index a43b30d723a4..030758d087d6 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_rtt.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_rtt.h @@ -21,9 +21,8 @@ void ar9003_hw_rtt_enable(struct ath_hw *ah); void ar9003_hw_rtt_disable(struct ath_hw *ah); void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask); bool ar9003_hw_rtt_force_restore(struct ath_hw *ah); -void ar9003_hw_rtt_load_hist(struct ath_hw *ah); -void ar9003_hw_rtt_fill_hist(struct ath_hw *ah); +void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table); +void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table); void ar9003_hw_rtt_clear_hist(struct ath_hw *ah); -bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan); #endif diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index abe05ec85d50..f84477c5ebb1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -1702,10 +1702,10 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) * For AR9462, make sure that calibration data for * re-using are present. */ - if (AR_SREV_9462(ah) && (ah->caldata && - (!ah->caldata->done_txiqcal_once || - !ah->caldata->done_txclcal_once || - !ah->caldata->rtt_done))) + if (AR_SREV_9462(ah) && (!ah->caldata || + !ah->caldata->done_txiqcal_once || + !ah->caldata->done_txclcal_once || + !ah->caldata->rtt_hist.num_readings)) goto fail; ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", @@ -1941,6 +1941,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (caldata) { caldata->done_txiqcal_once = false; caldata->done_txclcal_once = false; + caldata->rtt_hist.num_readings = 0; } if (!ath9k_hw_init_cal(ah, chan)) return -EIO; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index b620c557c2a6..828b9bbc456d 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -348,6 +348,12 @@ enum ath9k_int { CHANNEL_HT40MINUS) #define MAX_RTT_TABLE_ENTRY 6 +#define RTT_HIST_MAX 3 +struct ath9k_rtt_hist { + u32 table[AR9300_MAX_CHAINS][RTT_HIST_MAX][MAX_RTT_TABLE_ENTRY]; + u8 num_readings; +}; + #define MAX_IQCAL_MEASUREMENT 8 #define MAX_CL_TAB_ENTRY 16 @@ -357,7 +363,6 @@ struct ath9k_hw_cal_data { int32_t CalValid; int8_t iCoff; int8_t qCoff; - bool rtt_done; bool paprd_done; bool nfcal_pending; bool nfcal_interference; @@ -368,8 +373,8 @@ struct ath9k_hw_cal_data { u32 num_measures[AR9300_MAX_CHAINS]; int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS]; u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY]; - u32 rtt_table[AR9300_MAX_CHAINS][MAX_RTT_TABLE_ENTRY]; struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; + struct ath9k_rtt_hist rtt_hist; }; struct ath9k_channel { diff --git a/trunk/drivers/net/wireless/b43/bus.c b/trunk/drivers/net/wireless/b43/bus.c index 565fdbdd6915..424692df239d 100644 --- a/trunk/drivers/net/wireless/b43/bus.c +++ b/trunk/drivers/net/wireless/b43/bus.c @@ -107,9 +107,11 @@ struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core) dev->dma_dev = core->dma_dev; dev->irq = core->irq; + /* dev->board_vendor = core->bus->boardinfo.vendor; dev->board_type = core->bus->boardinfo.type; - dev->board_rev = core->bus->sprom.board_rev; + dev->board_rev = core->bus->boardinfo.rev; + */ dev->chip_id = core->bus->chipinfo.id; dev->chip_rev = core->bus->chipinfo.rev; @@ -208,7 +210,7 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) dev->board_vendor = sdev->bus->boardinfo.vendor; dev->board_type = sdev->bus->boardinfo.type; - dev->board_rev = sdev->bus->sprom.board_rev; + dev->board_rev = sdev->bus->boardinfo.rev; dev->chip_id = sdev->bus->chip_id; dev->chip_rev = sdev->bus->chip_rev; diff --git a/trunk/drivers/net/wireless/b43/dma.c b/trunk/drivers/net/wireless/b43/dma.c index 777cd74921d7..b5f1b91002bb 100644 --- a/trunk/drivers/net/wireless/b43/dma.c +++ b/trunk/drivers/net/wireless/b43/dma.c @@ -1109,7 +1109,7 @@ static bool b43_dma_translation_in_low_word(struct b43_wldev *dev, #ifdef CONFIG_B43_SSB if (dev->dev->bus_type == B43_BUS_SSB && dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && - !(pci_is_pcie(dev->dev->sdev->bus->host_pci) && + !(dev->dev->sdev->bus->host_pci->is_pcie && ssb_read32(dev->dev->sdev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64)) return 1; #endif diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 5a39b226b2e3..617afc8211b2 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -5243,10 +5243,10 @@ static void b43_sprom_fixup(struct ssb_bus *bus) /* boardflags workarounds */ if (bus->boardinfo.vendor == SSB_BOARDVENDOR_DELL && - bus->chip_id == 0x4301 && bus->sprom.board_rev == 0x74) + bus->chip_id == 0x4301 && bus->boardinfo.rev == 0x74) bus->sprom.boardflags_lo |= B43_BFL_BTCOEXIST; if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && - bus->boardinfo.type == 0x4E && bus->sprom.board_rev > 0x40) + bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40) bus->sprom.boardflags_lo |= B43_BFL_PACTRL; if (bus->bustype == SSB_BUSTYPE_PCI) { pdev = bus->host_pci; diff --git a/trunk/drivers/net/wireless/b43legacy/main.c b/trunk/drivers/net/wireless/b43legacy/main.c index cd9c9bc186d9..1be214b815fb 100644 --- a/trunk/drivers/net/wireless/b43legacy/main.c +++ b/trunk/drivers/net/wireless/b43legacy/main.c @@ -1573,6 +1573,8 @@ static void b43legacy_request_firmware(struct work_struct *work) const char *filename; int err; + /* do dummy read */ + ssb_read32(dev->dev, SSB_TMSHIGH); if (!fw->ucode) { if (rev == 2) filename = "ucode2"; @@ -3779,7 +3781,7 @@ static void b43legacy_sprom_fixup(struct ssb_bus *bus) /* boardflags workarounds */ if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && bus->boardinfo.type == 0x4E && - bus->sprom.board_rev > 0x40) + bus->boardinfo.rev > 0x40) bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL; } diff --git a/trunk/drivers/net/wireless/b43legacy/phy.c b/trunk/drivers/net/wireless/b43legacy/phy.c index 995c7d0c212a..950334197f40 100644 --- a/trunk/drivers/net/wireless/b43legacy/phy.c +++ b/trunk/drivers/net/wireless/b43legacy/phy.c @@ -408,7 +408,7 @@ static void b43legacy_phy_setupg(struct b43legacy_wldev *dev) if (is_bcm_board_vendor(dev) && (dev->dev->bus->boardinfo.type == 0x0416) && - (dev->dev->bus->sprom.board_rev == 0x0017)) + (dev->dev->bus->boardinfo.rev == 0x0017)) return; b43legacy_ilt_write(dev, 0x5001, 0x0002); @@ -424,7 +424,7 @@ static void b43legacy_phy_setupg(struct b43legacy_wldev *dev) if (is_bcm_board_vendor(dev) && (dev->dev->bus->boardinfo.type == 0x0416) && - (dev->dev->bus->sprom.board_rev == 0x0017)) + (dev->dev->bus->boardinfo.rev == 0x0017)) return; b43legacy_ilt_write(dev, 0x0401, 0x0002); diff --git a/trunk/drivers/net/wireless/b43legacy/radio.c b/trunk/drivers/net/wireless/b43legacy/radio.c index 896177690394..fcbafcd603cc 100644 --- a/trunk/drivers/net/wireless/b43legacy/radio.c +++ b/trunk/drivers/net/wireless/b43legacy/radio.c @@ -1998,7 +1998,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev) if (phy->type == B43legacy_PHYTYPE_G) { if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == 0x421 && - dev->dev->bus->sprom.board_rev >= 30) + dev->dev->bus->boardinfo.rev >= 30) att = 3; else if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == 0x416) @@ -2008,7 +2008,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev) } else { if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == 0x421 && - dev->dev->bus->sprom.board_rev >= 30) + dev->dev->bus->boardinfo.rev >= 30) att = 7; else att = 6; @@ -2018,7 +2018,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev) if (phy->type == B43legacy_PHYTYPE_G) { if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == 0x421 && - dev->dev->bus->sprom.board_rev >= 30) + dev->dev->bus->boardinfo.rev >= 30) att = 3; else if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == @@ -2052,9 +2052,9 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev) } if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == 0x421) { - if (dev->dev->bus->sprom.board_rev < 0x43) + if (dev->dev->bus->boardinfo.rev < 0x43) att = 2; - else if (dev->dev->bus->sprom.board_rev < 0x51) + else if (dev->dev->bus->boardinfo.rev < 0x51) att = 3; } if (att == 0xFFFF) diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index e2480d196276..4add7da24681 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -85,15 +85,18 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) sdiodev->irq_wake = true; /* must configure SDIO_CCCR_IENx to enable irq */ - data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); + data = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_0, + SDIO_CCCR_IENx, &ret); data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_IENx, + data, &ret); /* redirect, configure ane enable io for interrupt signal */ data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; if (sdiodev->irq_flags | IRQF_TRIGGER_HIGH) data |= SDIO_SEPINT_ACT_HI; - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_BRCM_SEPINT, + data, &ret); return 0; } @@ -102,8 +105,9 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) { brcmf_dbg(TRACE, "Entering\n"); - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_BRCM_SEPINT, + 0, NULL); + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_IENx, 0, NULL); if (sdiodev->irq_wake) { disable_irq_wake(sdiodev->irq); @@ -154,147 +158,153 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) } #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ -int -brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) +u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr, + int *err) { - int err = 0, i; - u8 addr[3]; - s32 retry; - - addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; - addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; - addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; - - for (i = 0; i < 3; i++) { - retry = 0; - do { - if (retry) - usleep_range(1000, 2000); - err = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, - SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW + i, - &addr[i]); - } while (err != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); - - if (err) { - brcmf_dbg(ERROR, "failed at addr:0x%0x\n", - SBSDIO_FUNC1_SBADDRLOW + i); - break; - } - } + int status; + s32 retry = 0; + u8 data = 0; - return err; + do { + if (retry) /* wait for 1 ms till bus get settled down */ + udelay(1000); + status = brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, fnc_num, + addr, (u8 *) &data); + } while (status != 0 + && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); + if (err) + *err = status; + + brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n", + fnc_num, addr, data); + + return data; } -static int -brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, - void *data, bool write) +void +brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr, + u8 data, int *err) { - u8 func_num, reg_size; - u32 bar; + int status; s32 retry = 0; - int ret; - - /* - * figure out how to read the register based on address range - * 0x00 ~ 0x7FF: function 0 CCCR and FBR - * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers - * The rest: function 1 silicon backplane core registers - */ - if ((addr & ~REG_F0_REG_MASK) == 0) { - func_num = SDIO_FUNC_0; - reg_size = 1; - } else if ((addr & ~REG_F1_MISC_MASK) == 0) { - func_num = SDIO_FUNC_1; - reg_size = 1; - } else { - func_num = SDIO_FUNC_1; - reg_size = 4; - - /* Set the window for SB core register */ - bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - if (bar != sdiodev->sbwad) { - ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar); - if (ret != 0) { - memset(data, 0xFF, reg_size); - return ret; - } - sdiodev->sbwad = bar; - } - addr &= SBSDIO_SB_OFT_ADDR_MASK; - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - } do { - if (!write) - memset(data, 0, reg_size); if (retry) /* wait for 1 ms till bus get settled down */ - usleep_range(1000, 2000); - if (reg_size == 1) - ret = brcmf_sdioh_request_byte(sdiodev, write, - func_num, addr, data); - else - ret = brcmf_sdioh_request_word(sdiodev, write, - func_num, addr, data, 4); - } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); + udelay(1000); + status = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, fnc_num, + addr, (u8 *) &data); + } while (status != 0 + && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); + if (err) + *err = status; - if (ret != 0) - brcmf_dbg(ERROR, "failed with %d\n", ret); + brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n", + fnc_num, addr, data); +} - return ret; +int +brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) +{ + int err = 0; + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, + (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); + if (!err) + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_SBADDRMID, + (address >> 16) & SBSDIO_SBADDRMID_MASK, + &err); + if (!err) + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_SBADDRHIGH, + (address >> 24) & SBSDIO_SBADDRHIGH_MASK, + &err); + + return err; } -u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) +u32 brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size) { - u8 data; - int retval; + int status; + u32 word = 0; + uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - brcmf_dbg(INFO, "addr:0x%08x\n", addr); - retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); - brcmf_dbg(INFO, "data:0x%02x\n", data); + brcmf_dbg(INFO, "fun = 1, addr = 0x%x\n", addr); - if (ret) - *ret = retval; + if (bar0 != sdiodev->sbwad) { + if (brcmf_sdcard_set_sbaddr_window(sdiodev, bar0)) + return 0xFFFFFFFF; - return data; -} + sdiodev->sbwad = bar0; + } -u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) -{ - u32 data; - int retval; + addr &= SBSDIO_SB_OFT_ADDR_MASK; + if (size == 4) + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - brcmf_dbg(INFO, "addr:0x%08x\n", addr); - retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); - brcmf_dbg(INFO, "data:0x%08x\n", data); + status = brcmf_sdioh_request_word(sdiodev, SDIOH_READ, SDIO_FUNC_1, + addr, &word, size); - if (ret) - *ret = retval; + sdiodev->regfail = (status != 0); - return data; -} + brcmf_dbg(INFO, "u32data = 0x%x\n", word); -void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, - u8 data, int *ret) -{ - int retval; + /* if ok, return appropriately masked word */ + if (status == 0) { + switch (size) { + case sizeof(u8): + return word & 0xff; + case sizeof(u16): + return word & 0xffff; + case sizeof(u32): + return word; + default: + sdiodev->regfail = true; - brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data); - retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); + } + } - if (ret) - *ret = retval; + /* otherwise, bad sdio access or invalid size */ + brcmf_dbg(ERROR, "error reading addr 0x%04x size %d\n", addr, size); + return 0xFFFFFFFF; } -void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, - u32 data, int *ret) +u32 brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size, + u32 data) { - int retval; + int status; + uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; + int err = 0; - brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data); - retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); + brcmf_dbg(INFO, "fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", + addr, size * 8, data); - if (ret) - *ret = retval; + if (bar0 != sdiodev->sbwad) { + err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); + if (err) + return err; + + sdiodev->sbwad = bar0; + } + + addr &= SBSDIO_SB_OFT_ADDR_MASK; + if (size == 4) + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + status = + brcmf_sdioh_request_word(sdiodev, SDIOH_WRITE, SDIO_FUNC_1, + addr, &data, size); + sdiodev->regfail = (status != 0); + + if (status == 0) + return 0; + + brcmf_dbg(ERROR, "error writing 0x%08x to addr 0x%04x size %d\n", + data, addr, size); + return 0xFFFFFFFF; +} + +bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev) +{ + return sdiodev->regfail; } static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn, diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 82f51dbd0d66..dd07d33a927c 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -346,17 +346,43 @@ int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev, return status; } +/* Read client card reg */ +static int +brcmf_sdioh_card_regread(struct brcmf_sdio_dev *sdiodev, int func, u32 regaddr, + int regsize, u32 *data) +{ + + if ((func == 0) || (regsize == 1)) { + u8 temp = 0; + + brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, func, regaddr, + &temp); + *data = temp; + *data &= 0xff; + brcmf_dbg(DATA, "byte read data=0x%02x\n", *data); + } else { + brcmf_sdioh_request_word(sdiodev, SDIOH_READ, func, regaddr, + data, regsize); + if (regsize == 2) + *data &= 0xffff; + + brcmf_dbg(DATA, "word read data=0x%08x\n", *data); + } + + return SUCCESS; +} + static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr) { /* read 24 bits and return valid 17 bit addr */ - int i, ret; + int i; u32 scratch, regdata; __le32 scratch_le; u8 *ptr = (u8 *)&scratch_le; for (i = 0; i < 3; i++) { - regdata = brcmf_sdio_regrl(sdiodev, regaddr, &ret); - if (ret != 0) + if ((brcmf_sdioh_card_regread(sdiodev, 0, regaddr, 1, + ®data)) != SUCCESS) brcmf_dbg(ERROR, "Can't read!\n"); *ptr++ = (u8) regdata; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 1dbf2be478c8..149ee67beb2e 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -629,29 +629,43 @@ static bool data_ok(struct brcmf_sdio *bus) * Reads a register in the SDIO hardware block. This block occupies a series of * adresses on the 32 bit backplane bus. */ -static int -r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset) +static void +r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) { u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); - int ret; - - *regvar = brcmf_sdio_regrl(bus->sdiodev, - bus->ci->c_inf[idx].base + offset, &ret); - - return ret; + *retryvar = 0; + do { + *regvar = brcmf_sdcard_reg_read(bus->sdiodev, + bus->ci->c_inf[idx].base + reg_offset, + sizeof(u32)); + } while (brcmf_sdcard_regfail(bus->sdiodev) && + (++(*retryvar) <= retry_limit)); + if (*retryvar) { + bus->regfails += (*retryvar-1); + if (*retryvar > retry_limit) { + brcmf_dbg(ERROR, "FAILED READ %Xh\n", reg_offset); + *regvar = 0; + } + } } -static int -w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset) +static void +w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset, u32 *retryvar) { u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); - int ret; - - brcmf_sdio_regwl(bus->sdiodev, - bus->ci->c_inf[idx].base + reg_offset, - regval, &ret); - - return ret; + *retryvar = 0; + do { + brcmf_sdcard_reg_write(bus->sdiodev, + bus->ci->c_inf[idx].base + reg_offset, + sizeof(u32), regval); + } while (brcmf_sdcard_regfail(bus->sdiodev) && + (++(*retryvar) <= retry_limit)); + if (*retryvar) { + bus->regfails += (*retryvar-1); + if (*retryvar > retry_limit) + brcmf_dbg(ERROR, "FAILED REGISTER WRITE %Xh\n", + reg_offset); + } } #define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) @@ -683,16 +697,16 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) clkreq = bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - clkreq, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); if (err) { brcmf_dbg(ERROR, "HT Avail request error: %d\n", err); return -EBADE; } /* Check current status */ - clkctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, &err); + clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err) { brcmf_dbg(ERROR, "HT Avail read error: %d\n", err); return -EBADE; @@ -701,8 +715,9 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) /* Go to pending and await interrupt if appropriate */ if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { /* Allow only clock-available interrupt */ - devctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_DEVICE_CTL, &err); + devctl = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, &err); if (err) { brcmf_dbg(ERROR, "Devctl error setting CA: %d\n", err); @@ -710,28 +725,30 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) } devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, devctl, &err); brcmf_dbg(INFO, "CLKCTL: set PENDING\n"); bus->clkstate = CLK_PENDING; return 0; } else if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ - devctl = brcmf_sdio_regrb(bus->sdiodev, + devctl = + brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, devctl, &err); } /* Otherwise, wait here (polling) for HT Avail */ timeout = jiffies + msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000); while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - clkctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, - &err); + clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + &err); if (time_after(jiffies, timeout)) break; else @@ -764,16 +781,17 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ - devctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_DEVICE_CTL, &err); + devctl = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, &err); devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, devctl, &err); } bus->clkstate = CLK_SDONLY; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - clkreq, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); brcmf_dbg(INFO, "CLKCTL: turned OFF\n"); if (err) { brcmf_dbg(ERROR, "Failed access turning clock off: %d\n", @@ -856,7 +874,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep) { - int ret; + uint retries = 0; brcmf_dbg(INFO, "request %s (currently %s)\n", sleep ? "SLEEP" : "WAKE", @@ -876,20 +894,22 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep) brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); /* Tell device to start using OOB wakeup */ - ret = w_sdreg32(bus, SMB_USE_OOB, - offsetof(struct sdpcmd_regs, tosbmailbox)); - if (ret != 0) + w_sdreg32(bus, SMB_USE_OOB, + offsetof(struct sdpcmd_regs, tosbmailbox), &retries); + if (retries > retry_limit) brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"); /* Turn off our contribution to the HT clock request */ brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); /* Isolate the bus */ - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - SBSDIO_DEVCTL_PADS_ISO, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, + SBSDIO_DEVCTL_PADS_ISO, NULL); /* Change state */ bus->sleeping = true; @@ -897,20 +917,21 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep) } else { /* Waking up: bus power up is ok, set local state */ - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - 0, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); /* Make sure the controller has the bus up */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); /* Send misc interrupt to indicate OOB not needed */ - ret = w_sdreg32(bus, 0, - offsetof(struct sdpcmd_regs, tosbmailboxdata)); - if (ret == 0) - ret = w_sdreg32(bus, SMB_DEV_INT, - offsetof(struct sdpcmd_regs, tosbmailbox)); - - if (ret != 0) + w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, tosbmailboxdata), + &retries); + if (retries <= retry_limit) + w_sdreg32(bus, SMB_DEV_INT, + offsetof(struct sdpcmd_regs, tosbmailbox), + &retries); + + if (retries > retry_limit) brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n"); /* Make sure we have SD bus access */ @@ -934,17 +955,17 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) u32 intstatus = 0; u32 hmb_data; u8 fcbits; - int ret; + uint retries = 0; brcmf_dbg(TRACE, "Enter\n"); /* Read mailbox data and ack that we did so */ - ret = r_sdreg32(bus, &hmb_data, - offsetof(struct sdpcmd_regs, tohostmailboxdata)); + r_sdreg32(bus, &hmb_data, + offsetof(struct sdpcmd_regs, tohostmailboxdata), &retries); - if (ret == 0) + if (retries <= retry_limit) w_sdreg32(bus, SMB_INT_ACK, - offsetof(struct sdpcmd_regs, tosbmailbox)); + offsetof(struct sdpcmd_regs, tosbmailbox), &retries); bus->f1regdata += 2; /* Dongle recomposed rx frames, accept them again */ @@ -1019,16 +1040,17 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) if (abort) brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, - SFC_RF_TERM, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_FRAMECTRL, + SFC_RF_TERM, &err); bus->f1regdata++; /* Wait until the packet has been flushed (device/FIFO stable) */ for (lastrbc = retries = 0xffff; retries > 0; retries--) { - hi = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_RFRAMEBCHI, &err); - lo = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_RFRAMEBCLO, &err); + hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_RFRAMEBCHI, NULL); + lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_RFRAMEBCLO, NULL); bus->f1regdata += 2; if ((hi == 0) && (lo == 0)) @@ -1048,11 +1070,11 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) if (rtx) { bus->rxrtx++; - err = w_sdreg32(bus, SMB_NAK, - offsetof(struct sdpcmd_regs, tosbmailbox)); + w_sdreg32(bus, SMB_NAK, + offsetof(struct sdpcmd_regs, tosbmailbox), &retries); bus->f1regdata++; - if (err == 0) + if (retries <= retry_limit) bus->rxskip = true; } @@ -1060,7 +1082,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) bus->nextlen = 0; /* If we can't reach the device, signal failure */ - if (err) + if (err || brcmf_sdcard_regfail(bus->sdiodev)) bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; } @@ -2156,16 +2178,21 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, bus->tx_sderrs++; brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, + NULL); bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); + hi = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, + SBSDIO_FUNC1_WFRAMEBCHI, + NULL); + lo = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, + SBSDIO_FUNC1_WFRAMEBCLO, + NULL); bus->f1regdata += 2; if ((hi == 0) && (lo == 0)) break; @@ -2192,6 +2219,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) { struct sk_buff *pkt; u32 intstatus = 0; + uint retries = 0; int ret = 0, prec_out; uint cnt = 0; uint datalen; @@ -2221,11 +2249,11 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) /* In poll mode, need to check for other events */ if (!bus->intr && cnt) { /* Check device status, signal pending interrupt */ - ret = r_sdreg32(bus, &intstatus, - offsetof(struct sdpcmd_regs, - intstatus)); + r_sdreg32(bus, &intstatus, + offsetof(struct sdpcmd_regs, intstatus), + &retries); bus->f2txdata++; - if (ret != 0) + if (brcmf_sdcard_regfail(bus->sdiodev)) break; if (intstatus & bus->hostintmask) bus->ipend = true; @@ -2247,6 +2275,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) { u32 local_hostintmask; u8 saveclk; + uint retries; int err; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; @@ -2274,7 +2303,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); /* Disable and clear interrupts at the chip level also */ - w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); + w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask), &retries); local_hostintmask = bus->hostintmask; bus->hostintmask = 0; @@ -2282,23 +2311,24 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, &err); + saveclk = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (!err) { - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + (saveclk | SBSDIO_FORCE_HT), &err); } if (err) brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err); /* Turn off the bus (F2), free any pending packets */ brcmf_dbg(INTR, "disable SDIO interrupts\n"); - brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1, - NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, + SDIO_FUNC_ENABLE_1, NULL); /* Clear any pending interrupts now that F2 is disabled */ w_sdreg32(bus, local_hostintmask, - offsetof(struct sdpcmd_regs, intstatus)); + offsetof(struct sdpcmd_regs, intstatus), &retries); /* Turn off the backplane clock (only) */ brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); @@ -2343,12 +2373,12 @@ static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus) static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) { u32 intstatus, newstatus = 0; + uint retries = 0; uint rxlimit = bus->rxbound; /* Rx frames to read before resched */ uint txlimit = bus->txbound; /* Tx frames to send before resched */ uint framecnt = 0; /* Temporary counter of tx/rx frames */ bool rxdone = true; /* Flag for no more read data */ bool resched = false; /* Flag indicating resched wanted */ - int err; brcmf_dbg(TRACE, "Enter\n"); @@ -2359,12 +2389,13 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) /* If waiting for HTAVAIL, check status */ if (bus->clkstate == CLK_PENDING) { + int err; u8 clkctl, devctl = 0; #ifdef DEBUG /* Check for inconsistent device control */ - devctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_DEVICE_CTL, &err); + devctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, &err); if (err) { brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err); bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; @@ -2372,8 +2403,8 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) #endif /* DEBUG */ /* Read CSR, if clock on switch to AVAIL, else ignore */ - clkctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, &err); + clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err) { brcmf_dbg(ERROR, "error reading CSR: %d\n", err); @@ -2384,16 +2415,17 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) devctl, clkctl); if (SBSDIO_HTAV(clkctl)) { - devctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_DEVICE_CTL, &err); + devctl = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, &err); if (err) { brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err); bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; } devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, devctl, &err); if (err) { brcmf_dbg(ERROR, "error writing DEVCTL: %d\n", err); @@ -2415,17 +2447,17 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) /* Pending interrupt indicates new device status */ if (bus->ipend) { bus->ipend = false; - err = r_sdreg32(bus, &newstatus, - offsetof(struct sdpcmd_regs, intstatus)); + r_sdreg32(bus, &newstatus, + offsetof(struct sdpcmd_regs, intstatus), &retries); bus->f1regdata++; - if (err != 0) + if (brcmf_sdcard_regfail(bus->sdiodev)) newstatus = 0; newstatus &= bus->hostintmask; bus->fcstate = !!(newstatus & I_HMB_FC_STATE); if (newstatus) { - err = w_sdreg32(bus, newstatus, - offsetof(struct sdpcmd_regs, - intstatus)); + w_sdreg32(bus, newstatus, + offsetof(struct sdpcmd_regs, intstatus), + &retries); bus->f1regdata++; } } @@ -2440,11 +2472,11 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) */ if (intstatus & I_HMB_FC_CHANGE) { intstatus &= ~I_HMB_FC_CHANGE; - err = w_sdreg32(bus, I_HMB_FC_CHANGE, - offsetof(struct sdpcmd_regs, intstatus)); + w_sdreg32(bus, I_HMB_FC_CHANGE, + offsetof(struct sdpcmd_regs, intstatus), &retries); - err = r_sdreg32(bus, &newstatus, - offsetof(struct sdpcmd_regs, intstatus)); + r_sdreg32(bus, &newstatus, + offsetof(struct sdpcmd_regs, intstatus), &retries); bus->f1regdata += 2; bus->fcstate = !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); @@ -2514,18 +2546,21 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, + NULL); bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCHI, - &err); - lo = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCLO, - &err); + hi = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, + SBSDIO_FUNC1_WFRAMEBCHI, + NULL); + lo = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, + SBSDIO_FUNC1_WFRAMEBCLO, + NULL); bus->f1regdata += 2; if ((hi == 0) && (lo == 0)) break; @@ -2552,8 +2587,10 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) else await next interrupt */ /* On failed register access, all bets are off: no resched or interrupts */ - if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) { - brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation\n"); + if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || + brcmf_sdcard_regfail(bus->sdiodev)) { + brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation %d\n", + brcmf_sdcard_regfail(bus->sdiodev)); bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; bus->intstatus = 0; } else if (bus->clkstate == CLK_PENDING) { @@ -2849,16 +2886,19 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_FRAMECTRL, + SFC_WF_TERM, NULL); bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); + hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_WFRAMEBCHI, + NULL); + lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_WFRAMEBCLO, + NULL); bus->f1regdata += 2; if (hi == 0 && lo == 0) break; @@ -3148,6 +3188,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) { + uint retries; int bcmerror = 0; struct chip_info *ci = bus->ci; @@ -3181,7 +3222,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) } w_sdreg32(bus, 0xFFFFFFFF, - offsetof(struct sdpcmd_regs, intstatus)); + offsetof(struct sdpcmd_regs, intstatus), &retries); ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); @@ -3403,6 +3444,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; unsigned long timeout; + uint retries = 0; u8 ready, enable; int err, ret = 0; u8 saveclk; @@ -3430,11 +3472,13 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) goto exit; /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, &err); + saveclk = + brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (!err) { - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + (saveclk | SBSDIO_FORCE_HT), &err); } if (err) { brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err); @@ -3443,16 +3487,17 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) /* Enable function 2 (frame transfers) */ w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, - offsetof(struct sdpcmd_regs, tosbmailboxdata)); + offsetof(struct sdpcmd_regs, tosbmailboxdata), &retries); enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); - brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, + enable, NULL); timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY); ready = 0; while (enable != ready) { - ready = brcmf_sdio_regrb(bus->sdiodev, - SDIO_CCCR_IORx, NULL); + ready = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_0, + SDIO_CCCR_IORx, NULL); if (time_after(jiffies, timeout)) break; else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50)) @@ -3467,18 +3512,21 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) /* Set up the interrupt mask and enable interrupts */ bus->hostintmask = HOSTINTMASK; w_sdreg32(bus, bus->hostintmask, - offsetof(struct sdpcmd_regs, hostintmask)); + offsetof(struct sdpcmd_regs, hostintmask), &retries); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_WATERMARK, 8, &err); } else { /* Disable F2 again */ enable = SDIO_FUNC_ENABLE_1; - brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, + SDIO_CCCR_IOEx, enable, NULL); ret = -ENODEV; } /* Restore previous clock setting */ - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); if (ret == 0) { ret = brcmf_sdio_intr_register(bus->sdiodev); @@ -3558,9 +3606,9 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) if (!bus->dpc_sched) { u8 devpend; - devpend = brcmf_sdio_regrb(bus->sdiodev, - SDIO_CCCR_INTx, - NULL); + devpend = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_0, SDIO_CCCR_INTx, + NULL); intstatus = devpend & (INTR_STATUS_FUNC1 | INTR_STATUS_FUNC2); @@ -3684,18 +3732,24 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) bus->alp_only = true; + /* Return the window to backplane enumeration space for core access */ + if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE)) + brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n"); + pr_debug("F1 signature read @0x18000000=0x%4x\n", - brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); + brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4)); /* * Force PLL off until brcmf_sdio_chip_attach() * programs PLL control regs */ - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - BRCMF_INIT_CLKCTL1, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + BRCMF_INIT_CLKCTL1, &err); if (!err) - clkctl = brcmf_sdio_regrb(bus->sdiodev, + clkctl = + brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { @@ -3728,8 +3782,9 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); reg_addr = bus->ci->c_inf[idx].base + offsetof(struct sdpcmd_regs, corecontrol); - reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL); - brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL); + reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32)); + brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32), + reg_val | CC_BPRESEN); brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); @@ -3754,15 +3809,16 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) brcmf_dbg(TRACE, "Enter\n"); /* Disable F2 to clear any intermediate frame state on the dongle */ - brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, - SDIO_FUNC_ENABLE_1, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, + SDIO_FUNC_ENABLE_1, NULL); bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; bus->sleeping = false; bus->rxflow = false; /* Done with backplane-dependent accesses, can drop clock... */ - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); /* ...and initialize clock/power states */ bus->clkstate = CLK_SDONLY; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index f8e1f1c84d08..1534efc21631 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -93,9 +93,8 @@ brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev, idx = brcmf_sdio_chip_getinfidx(ci, coreid); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbidhigh), - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbidhigh), 4); return SBCOREREV(regdata); } @@ -119,9 +118,8 @@ brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev, idx = brcmf_sdio_chip_getinfidx(ci, coreid); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT | SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK); return (SSB_TMSLOW_CLOCK == regdata); @@ -137,13 +135,13 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, idx = brcmf_sdio_chip_getinfidx(ci, coreid); - regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK; - regdata = brcmf_sdio_regrl(sdiodev, - ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, + 4); ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0); return ret; @@ -153,85 +151,84 @@ static void brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, u16 coreid) { - u32 regdata, base; + u32 regdata; u8 idx; idx = brcmf_sdio_chip_getinfidx(ci, coreid); - base = ci->c_inf[idx].base; - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); if (regdata & SSB_TMSLOW_RESET) return; - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); if ((regdata & SSB_TMSLOW_CLOCK) != 0) { /* * set target reject and spin until busy is clear * (preserve core-specific bits) */ - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), - NULL); - brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow), - regdata | SSB_TMSLOW_REJECT, NULL); - - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); + brcmf_sdcard_reg_write(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), + 4, regdata | SSB_TMSLOW_REJECT); + + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); udelay(1); - SPINWAIT((brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbtmstatehigh), - NULL) & + SPINWAIT((brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4) & SSB_TMSHIGH_BUSY), 100000); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbtmstatehigh), - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4); if (regdata & SSB_TMSHIGH_BUSY) brcmf_dbg(ERROR, "core state still busy\n"); - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow), - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbidlow), 4); if (regdata & SSB_IDLOW_INITIATOR) { - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbimstate), - NULL); - regdata |= SSB_IMSTATE_REJECT; - brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate), - regdata, NULL); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbimstate), - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbimstate), 4) | + SSB_IMSTATE_REJECT; + brcmf_sdcard_reg_write(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbimstate), 4, + regdata); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbimstate), 4); udelay(1); - SPINWAIT((brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbimstate), - NULL) & + SPINWAIT((brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbimstate), 4) & SSB_IMSTATE_BUSY), 100000); } /* set reset and reject while enabling the clocks */ - regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | - SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET; - brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow), - regdata, NULL); - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), - NULL); + brcmf_sdcard_reg_write(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, + (SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | + SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET)); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); udelay(10); /* clear the initiator reject bit */ - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow), - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbidlow), 4); if (regdata & SSB_IDLOW_INITIATOR) { - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbimstate), - NULL); - regdata &= ~SSB_IMSTATE_REJECT; - brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate), - regdata, NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbimstate), 4) & + ~SSB_IMSTATE_REJECT; + brcmf_sdcard_reg_write(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbimstate), 4, + regdata); } } /* leave reset and reject asserted */ - brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow), - (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL); + brcmf_sdcard_reg_write(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, + (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET)); udelay(1); } @@ -245,19 +242,20 @@ brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, idx = brcmf_sdio_chip_getinfidx(ci, coreid); /* if core is already in reset, just return */ - regdata = brcmf_sdio_regrl(sdiodev, - ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, + 4); if ((regdata & BCMA_RESET_CTL_RESET) != 0) return; - brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 0, NULL); - regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - NULL); + brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + 4, 0); + regdata = brcmf_sdcard_reg_read(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); udelay(10); - brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - BCMA_RESET_CTL_RESET, NULL); + brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, + 4, BCMA_RESET_CTL_RESET); udelay(1); } @@ -281,47 +279,41 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, * set reset while enabling the clock and * forcing them on throughout the core */ - brcmf_sdio_regwl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET, - NULL); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - NULL); + brcmf_sdcard_reg_write(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); udelay(1); /* clear any serror */ - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4); if (regdata & SSB_TMSHIGH_SERR) - brcmf_sdio_regwl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), - 0, NULL); + brcmf_sdcard_reg_write(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4, 0); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbimstate), - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbimstate), 4); if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) - brcmf_sdio_regwl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbimstate), - regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO), - NULL); + brcmf_sdcard_reg_write(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbimstate), 4, + regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO)); /* clear reset and allow it to propagate throughout the core */ - brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - NULL); + brcmf_sdcard_reg_write(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); udelay(1); /* leave clock enabled */ - brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - SSB_TMSLOW_CLOCK, NULL); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - NULL); + brcmf_sdcard_reg_write(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), + 4, SSB_TMSLOW_CLOCK); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); udelay(1); } @@ -338,18 +330,18 @@ brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, brcmf_sdio_ai_coredisable(sdiodev, ci, coreid); /* now do initialization sequence */ - brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); - regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - NULL); - brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - 0, NULL); + brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + 4, BCMA_IOCTL_FGC | BCMA_IOCTL_CLK); + regdata = brcmf_sdcard_reg_read(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); + brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, + 4, 0); udelay(1); - brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - BCMA_IOCTL_CLK, NULL); - regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - NULL); + brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + 4, BCMA_IOCTL_CLK); + regdata = brcmf_sdcard_reg_read(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); udelay(1); } @@ -366,9 +358,8 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, */ ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON; ci->c_inf[0].base = regs; - regdata = brcmf_sdio_regrl(sdiodev, - CORE_CC_REG(ci->c_inf[0].base, chipid), - NULL); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_CC_REG(ci->c_inf[0].base, chipid), 4); ci->chip = regdata & CID_ID_MASK; ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; @@ -437,7 +428,8 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) /* Try forcing SDIO core to do ALPAvail request only */ clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; - brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); if (err) { brcmf_dbg(ERROR, "error writing for HT off\n"); return err; @@ -445,8 +437,8 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) /* If register supported, wait for ALPAvail and then force ALP */ /* This may take up to 15 milliseconds */ - clkval = brcmf_sdio_regrb(sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, NULL); + clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, NULL); if ((clkval & ~SBSDIO_AVBITS) != clkset) { brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n", @@ -454,8 +446,8 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) return -EACCES; } - SPINWAIT(((clkval = brcmf_sdio_regrb(sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, NULL)), + SPINWAIT(((clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)), PMU_MAX_TRANSITION_DLY); if (!SBSDIO_ALPAV(clkval)) { @@ -465,11 +457,13 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) } clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; - brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); udelay(65); /* Also, disable the extra SDIO pull-ups */ - brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); return 0; } @@ -478,22 +472,18 @@ static void brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) { - u32 base = ci->c_inf[0].base; - /* get chipcommon rev */ ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id); /* get chipcommon capabilites */ - ci->c_inf[0].caps = brcmf_sdio_regrl(sdiodev, - CORE_CC_REG(base, capabilities), - NULL); + ci->c_inf[0].caps = + brcmf_sdcard_reg_read(sdiodev, + CORE_CC_REG(ci->c_inf[0].base, capabilities), 4); /* get pmu caps & rev */ if (ci->c_inf[0].caps & CC_CAP_PMU) { - ci->pmucaps = - brcmf_sdio_regrl(sdiodev, - CORE_CC_REG(base, pmucapabilities), - NULL); + ci->pmucaps = brcmf_sdcard_reg_read(sdiodev, + CORE_CC_REG(ci->c_inf[0].base, pmucapabilities), 4); ci->pmurev = ci->pmucaps & PCAP_REV_MASK; } @@ -533,10 +523,10 @@ int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, brcmf_sdio_chip_buscoresetup(sdiodev, ci); - brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup), - 0, NULL); - brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), - 0, NULL); + brcmf_sdcard_reg_write(sdiodev, + CORE_CC_REG(ci->c_inf[0].base, gpiopullup), 4, 0); + brcmf_sdcard_reg_write(sdiodev, + CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), 4, 0); *ci_ptr = ci; return 0; @@ -572,7 +562,6 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, u32 str_mask = 0; u32 str_shift = 0; char chn[8]; - u32 base = ci->c_inf[0].base; if (!(ci->c_inf[0].caps & CC_CAP_PMU)) return; @@ -602,17 +591,17 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, } } - brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr), - 1, NULL); - cc_data_temp = - brcmf_sdio_regrl(sdiodev, - CORE_CC_REG(base, chipcontrol_addr), - NULL); + brcmf_sdcard_reg_write(sdiodev, + CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), + 4, 1); + cc_data_temp = brcmf_sdcard_reg_read(sdiodev, + CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), 4); cc_data_temp &= ~str_mask; drivestrength_sel <<= str_shift; cc_data_temp |= drivestrength_sel; - brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr), - cc_data_temp, NULL); + brcmf_sdcard_reg_write(sdiodev, + CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), + 4, cc_data_temp); brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n", drivestrength, cc_data_temp); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index 29bf78d264e0..7010eaf71f99 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -40,10 +40,6 @@ /* Maximum number of I/O funcs */ #define SDIOD_MAX_IOFUNCS 7 -/* mask of register map */ -#define REG_F0_REG_MASK 0x7FF -#define REG_F1_MISC_MASK 0x1FFFF - /* as of sdiod rev 0, supports 3 functions */ #define SBSDIO_NUM_FUNCTION 3 @@ -146,6 +142,7 @@ struct brcmf_sdio_dev { u8 num_funcs; /* Supported funcs on client */ u32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; u32 sbwad; /* Save backplane window address */ + bool regfail; /* status of last reg_r/w call */ void *bus; atomic_t suspend; /* suspend flag */ wait_queue_head_t request_byte_wait; @@ -167,13 +164,31 @@ struct brcmf_sdio_dev { extern int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev); extern int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev); -/* sdio device register access interface */ -extern u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); -extern u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); -extern void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, - u8 data, int *ret); -extern void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, - u32 data, int *ret); +/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface). + * fn: function number + * addr: unmodified SDIO-space address + * data: data byte to write + * err: pointer to error code (or NULL) + */ +extern u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint func, + u32 addr, int *err); +extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint func, + u32 addr, u8 data, int *err); + +/* Synchronous access to device (client) core registers via CMD53 to F1. + * addr: backplane address (i.e. >= regsva from attach) + * size: register width in bytes (2 or 4) + * data: data for register write + */ +extern u32 +brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size); + +extern u32 +brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size, + u32 data); + +/* Indicate if last reg read/write failed */ +extern bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev); /* Buffer transfer to/from device (client) core via cmd53. * fn: function number diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile index e227c4c68ef9..c2eb2d0af386 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile @@ -39,7 +39,10 @@ BRCMSMAC_OFILES := \ phy/phytbl_lcn.o \ phy/phytbl_n.o \ phy/phy_qmath.o \ + otp.o \ + srom.o \ dma.o \ + nicpci.o \ brcms_trace_events.o MODULEPFX := brcmsmac diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c index 6d8b7213643a..c93ea35bceec 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c @@ -19,6 +19,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include @@ -28,6 +29,8 @@ #include "types.h" #include "pub.h" #include "pmu.h" +#include "srom.h" +#include "nicpci.h" #include "aiutils.h" /* slow_clk_ctl */ @@ -318,6 +321,7 @@ #define IS_SIM(chippkg) \ ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) +#define PCI(sih) (ai_get_buscoretype(sih) == PCI_CORE_ID) #define PCIE(sih) (ai_get_buscoretype(sih) == PCIE_CORE_ID) #define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID)) @@ -450,9 +454,36 @@ struct aidmp { u32 componentid3; /* 0xffc */ }; +/* return true if PCIE capability exists in the pci config space */ +static bool ai_ispcie(struct si_info *sii) +{ + u8 cap_ptr; + + cap_ptr = + pcicore_find_pci_capability(sii->pcibus, PCI_CAP_ID_EXP, NULL, + NULL); + if (!cap_ptr) + return false; + + return true; +} + +static bool ai_buscore_prep(struct si_info *sii) +{ + /* kludge to enable the clock on the 4306 which lacks a slowclock */ + if (!ai_ispcie(sii)) + ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON); + return true; +} + static bool ai_buscore_setup(struct si_info *sii, struct bcma_device *cc) { + struct bcma_device *pci = NULL; + struct bcma_device *pcie = NULL; + struct bcma_device *core; + + /* no cores found, bail out */ if (cc->bus->nr_cores == 0) return false; @@ -461,7 +492,8 @@ ai_buscore_setup(struct si_info *sii, struct bcma_device *cc) sii->pub.ccrev = cc->id.rev; /* get chipcommon chipstatus */ - sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus)); + if (ai_get_ccrev(&sii->pub) >= 11) + sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus)); /* get chipcommon capabilites */ sii->pub.cccaps = bcma_read32(cc, CHIPCREGOFFS(capabilities)); @@ -474,18 +506,64 @@ ai_buscore_setup(struct si_info *sii, struct bcma_device *cc) } /* figure out buscore */ - sii->buscore = ai_findcore(&sii->pub, PCIE_CORE_ID, 0); + list_for_each_entry(core, &cc->bus->cores, list) { + uint cid, crev; + + cid = core->id.id; + crev = core->id.rev; + + if (cid == PCI_CORE_ID) { + pci = core; + } else if (cid == PCIE_CORE_ID) { + pcie = core; + } + } + + if (pci && pcie) { + if (ai_ispcie(sii)) + pci = NULL; + else + pcie = NULL; + } + if (pci) { + sii->buscore = pci; + } else if (pcie) { + sii->buscore = pcie; + } + + /* fixup necessary chip/core configurations */ + if (!sii->pch) { + sii->pch = pcicore_init(&sii->pub, sii->icbus->drv_pci.core); + if (sii->pch == NULL) + return false; + } + if (ai_pci_fixcfg(&sii->pub)) + return false; return true; } +/* + * get boardtype and boardrev + */ +static __used void ai_nvram_process(struct si_info *sii) +{ + uint w = 0; + + /* do a pci config read to get subsystem id and subvendor id */ + pci_read_config_dword(sii->pcibus, PCI_SUBSYSTEM_VENDOR_ID, &w); + + sii->pub.boardvendor = w & 0xffff; + sii->pub.boardtype = (w >> 16) & 0xffff; +} + static struct si_info *ai_doattach(struct si_info *sii, struct bcma_bus *pbus) { struct si_pub *sih = &sii->pub; u32 w, savewin; struct bcma_device *cc; - struct ssb_sprom *sprom = &pbus->sprom; + uint socitype; savewin = 0; @@ -495,15 +573,38 @@ static struct si_info *ai_doattach(struct si_info *sii, /* switch to Chipcommon core */ cc = pbus->drv_cc.core; - sih->chip = pbus->chipinfo.id; - sih->chiprev = pbus->chipinfo.rev; - sih->chippkg = pbus->chipinfo.pkg; - sih->boardvendor = pbus->boardinfo.vendor; - sih->boardtype = pbus->boardinfo.type; + /* bus/core/clk setup for register access */ + if (!ai_buscore_prep(sii)) + return NULL; + /* + * ChipID recognition. + * We assume we can read chipid at offset 0 from the regs arg. + * If we add other chiptypes (or if we need to support old sdio + * hosts w/o chipcommon), some way of recognizing them needs to + * be added here. + */ + w = bcma_read32(cc, CHIPCREGOFFS(chipid)); + socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; + /* Might as wll fill in chip id rev & pkg */ + sih->chip = w & CID_ID_MASK; + sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; + sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; + + /* scan for cores */ + if (socitype != SOCI_AI) + return NULL; + + SI_MSG("Found chip type AI (0x%08x)\n", w); if (!ai_buscore_setup(sii, cc)) goto exit; + /* Init nvram from sprom/otp if they exist */ + if (srom_var_init(&sii->pub)) + goto exit; + + ai_nvram_process(sii); + /* === NVRAM, clock is ready === */ bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0); bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0); @@ -516,13 +617,15 @@ static struct si_info *ai_doattach(struct si_info *sii, } /* setup the GPIO based LED powersave register */ - w = (sprom->leddc_on_time << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) | - (sprom->leddc_off_time << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT); + w = getintvar(sih, BRCMS_SROM_LEDDC); if (w == 0) w = DEFAULT_GPIOTIMERVAL; ai_cc_reg(sih, offsetof(struct chipcregs, gpiotimerval), ~0, w); + if (PCIE(sih)) + pcicore_attach(sii->pch, SI_DOATTACH); + if (ai_get_chip_id(sih) == BCM43224_CHIP_ID) { /* * enable 12 mA drive strenth for 43224 and @@ -556,6 +659,9 @@ static struct si_info *ai_doattach(struct si_info *sii, return sii; exit: + if (sii->pch) + pcicore_deinit(sii->pch); + sii->pch = NULL; return NULL; } @@ -594,6 +700,11 @@ void ai_detach(struct si_pub *sih) if (sii == NULL) return; + if (sii->pch) + pcicore_deinit(sii->pch); + sii->pch = NULL; + + srom_free_vars(sih); kfree(sii); } @@ -644,7 +755,21 @@ uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val) /* return the slow clock source - LPO, XTAL, or PCI */ static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc) { - return SCC_SS_XTAL; + struct si_info *sii; + u32 val; + + sii = (struct si_info *)sih; + if (ai_get_ccrev(&sii->pub) < 6) { + pci_read_config_dword(sii->pcibus, PCI_GPIO_OUT, + &val); + if (val & PCI_CFG_GPIO_SCS) + return SCC_SS_PCI; + return SCC_SS_XTAL; + } else if (ai_get_ccrev(&sii->pub) < 10) { + return bcma_read32(cc, CHIPCREGOFFS(slow_clk_ctl)) & + SCC_SS_MASK; + } else /* Insta-clock */ + return SCC_SS_XTAL; } /* @@ -654,12 +779,36 @@ static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc) static uint ai_slowclk_freq(struct si_pub *sih, bool max_freq, struct bcma_device *cc) { + u32 slowclk; uint div; - /* Chipc rev 10 is InstaClock */ - div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl)); - div = 4 * ((div >> SYCC_CD_SHIFT) + 1); - return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div); + slowclk = ai_slowclk_src(sih, cc); + if (ai_get_ccrev(sih) < 6) { + if (slowclk == SCC_SS_PCI) + return max_freq ? (PCIMAXFREQ / 64) + : (PCIMINFREQ / 64); + else + return max_freq ? (XTALMAXFREQ / 32) + : (XTALMINFREQ / 32); + } else if (ai_get_ccrev(sih) < 10) { + div = 4 * + (((bcma_read32(cc, CHIPCREGOFFS(slow_clk_ctl)) & + SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); + if (slowclk == SCC_SS_LPO) + return max_freq ? LPOMAXFREQ : LPOMINFREQ; + else if (slowclk == SCC_SS_XTAL) + return max_freq ? (XTALMAXFREQ / div) + : (XTALMINFREQ / div); + else if (slowclk == SCC_SS_PCI) + return max_freq ? (PCIMAXFREQ / div) + : (PCIMINFREQ / div); + } else { + /* Chipc rev 10 is InstaClock */ + div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl)); + div = 4 * ((div >> SYCC_CD_SHIFT) + 1); + return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div); + } + return 0; } static void @@ -682,7 +831,8 @@ ai_clkctl_setdelay(struct si_pub *sih, struct bcma_device *cc) /* Starting with 4318 it is ILP that is used for the delays */ slowmaxfreq = - ai_slowclk_freq(sih, false, cc); + ai_slowclk_freq(sih, + (ai_get_ccrev(sih) >= 10) ? false : true, cc); pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; @@ -704,8 +854,9 @@ void ai_clkctl_init(struct si_pub *sih) return; /* set all Instaclk chip ILP to 1 MHz */ - bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK, - (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); + if (ai_get_ccrev(sih) >= 10) + bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK, + (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); ai_clkctl_setdelay(sih, cc); } @@ -740,6 +891,140 @@ u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih) return fpdelay; } +/* turn primary xtal and/or pll off/on */ +int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on) +{ + struct si_info *sii; + u32 in, out, outen; + + sii = (struct si_info *)sih; + + /* pcie core doesn't have any mapping to control the xtal pu */ + if (PCIE(sih)) + return -1; + + pci_read_config_dword(sii->pcibus, PCI_GPIO_IN, &in); + pci_read_config_dword(sii->pcibus, PCI_GPIO_OUT, &out); + pci_read_config_dword(sii->pcibus, PCI_GPIO_OUTEN, &outen); + + /* + * Avoid glitching the clock if GPRS is already using it. + * We can't actually read the state of the PLLPD so we infer it + * by the value of XTAL_PU which *is* readable via gpioin. + */ + if (on && (in & PCI_CFG_GPIO_XTAL)) + return 0; + + if (what & XTAL) + outen |= PCI_CFG_GPIO_XTAL; + if (what & PLL) + outen |= PCI_CFG_GPIO_PLL; + + if (on) { + /* turn primary xtal on */ + if (what & XTAL) { + out |= PCI_CFG_GPIO_XTAL; + if (what & PLL) + out |= PCI_CFG_GPIO_PLL; + pci_write_config_dword(sii->pcibus, + PCI_GPIO_OUT, out); + pci_write_config_dword(sii->pcibus, + PCI_GPIO_OUTEN, outen); + udelay(XTAL_ON_DELAY); + } + + /* turn pll on */ + if (what & PLL) { + out &= ~PCI_CFG_GPIO_PLL; + pci_write_config_dword(sii->pcibus, + PCI_GPIO_OUT, out); + mdelay(2); + } + } else { + if (what & XTAL) + out &= ~PCI_CFG_GPIO_XTAL; + if (what & PLL) + out |= PCI_CFG_GPIO_PLL; + pci_write_config_dword(sii->pcibus, + PCI_GPIO_OUT, out); + pci_write_config_dword(sii->pcibus, + PCI_GPIO_OUTEN, outen); + } + + return 0; +} + +/* clk control mechanism through chipcommon, no policy checking */ +static bool _ai_clkctl_cc(struct si_info *sii, uint mode) +{ + struct bcma_device *cc; + u32 scc; + + /* chipcommon cores prior to rev6 don't support dynamic clock control */ + if (ai_get_ccrev(&sii->pub) < 6) + return false; + + cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0); + + if (!(ai_get_cccaps(&sii->pub) & CC_CAP_PWR_CTL) && + (ai_get_ccrev(&sii->pub) < 20)) + return mode == CLK_FAST; + + switch (mode) { + case CLK_FAST: /* FORCEHT, fast (pll) clock */ + if (ai_get_ccrev(&sii->pub) < 10) { + /* + * don't forget to force xtal back + * on before we clear SCC_DYN_XTAL.. + */ + ai_clkctl_xtal(&sii->pub, XTAL, ON); + bcma_maskset32(cc, CHIPCREGOFFS(slow_clk_ctl), + (SCC_XC | SCC_FS | SCC_IP), SCC_IP); + } else if (ai_get_ccrev(&sii->pub) < 20) { + bcma_set32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_HR); + } else { + bcma_set32(cc, CHIPCREGOFFS(clk_ctl_st), CCS_FORCEHT); + } + + /* wait for the PLL */ + if (ai_get_cccaps(&sii->pub) & CC_CAP_PMU) { + u32 htavail = CCS_HTAVAIL; + SPINWAIT(((bcma_read32(cc, CHIPCREGOFFS(clk_ctl_st)) & + htavail) == 0), PMU_MAX_TRANSITION_DLY); + } else { + udelay(PLL_DELAY); + } + break; + + case CLK_DYNAMIC: /* enable dynamic clock control */ + if (ai_get_ccrev(&sii->pub) < 10) { + scc = bcma_read32(cc, CHIPCREGOFFS(slow_clk_ctl)); + scc &= ~(SCC_FS | SCC_IP | SCC_XC); + if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) + scc |= SCC_XC; + bcma_write32(cc, CHIPCREGOFFS(slow_clk_ctl), scc); + + /* + * for dynamic control, we have to + * release our xtal_pu "force on" + */ + if (scc & SCC_XC) + ai_clkctl_xtal(&sii->pub, XTAL, OFF); + } else if (ai_get_ccrev(&sii->pub) < 20) { + /* Instaclock */ + bcma_mask32(cc, CHIPCREGOFFS(system_clk_ctl), ~SYCC_HR); + } else { + bcma_mask32(cc, CHIPCREGOFFS(clk_ctl_st), ~CCS_FORCEHT); + } + break; + + default: + break; + } + + return mode == CLK_FAST; +} + /* * clock control policy function throught chipcommon * @@ -748,53 +1033,133 @@ u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih) * this is a wrapper over the next internal function * to allow flexible policy settings for outside caller */ -bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode) +bool ai_clkctl_cc(struct si_pub *sih, uint mode) { struct si_info *sii; - struct bcma_device *cc; sii = (struct si_info *)sih; + /* chipcommon cores prior to rev6 don't support dynamic clock control */ + if (ai_get_ccrev(sih) < 6) + return false; + if (PCI_FORCEHT(sih)) - return mode == BCMA_CLKMODE_FAST; + return mode == CLK_FAST; - cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0); - bcma_core_set_clockmode(cc, mode); - return mode == BCMA_CLKMODE_FAST; + return _ai_clkctl_cc(sii, mode); } void ai_pci_up(struct si_pub *sih) { struct si_info *sii; - struct bcma_device *cc; sii = (struct si_info *)sih; - if (PCI_FORCEHT(sih)) { - cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0); - bcma_core_set_clockmode(cc, BCMA_CLKMODE_FAST); - } + if (PCI_FORCEHT(sih)) + _ai_clkctl_cc(sii, CLK_FAST); if (PCIE(sih)) - bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, true); + pcicore_up(sii->pch, SI_PCIUP); + +} + +/* Unconfigure and/or apply various WARs when system is going to sleep mode */ +void ai_pci_sleep(struct si_pub *sih) +{ + struct si_info *sii; + + sii = (struct si_info *)sih; + + pcicore_sleep(sii->pch); } /* Unconfigure and/or apply various WARs when going down */ void ai_pci_down(struct si_pub *sih) { struct si_info *sii; - struct bcma_device *cc; sii = (struct si_info *)sih; /* release FORCEHT since chip is going to "down" state */ - if (PCI_FORCEHT(sih)) { - cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0); - bcma_core_set_clockmode(cc, BCMA_CLKMODE_DYNAMIC); + if (PCI_FORCEHT(sih)) + _ai_clkctl_cc(sii, CLK_DYNAMIC); + + pcicore_down(sii->pch, SI_PCIDOWN); +} + +/* + * Configure the pci core for pci client (NIC) action + * coremask is the bitvec of cores by index to be enabled. + */ +void ai_pci_setup(struct si_pub *sih, uint coremask) +{ + struct si_info *sii; + u32 w; + + sii = (struct si_info *)sih; + + /* + * Enable sb->pci interrupts. Assume + * PCI rev 2.3 support was added in pci core rev 6 and things changed.. + */ + if (PCIE(sih) || (PCI(sih) && (ai_get_buscorerev(sih) >= 6))) { + /* pci config write to set this core bit in PCIIntMask */ + pci_read_config_dword(sii->pcibus, PCI_INT_MASK, &w); + w |= (coremask << PCI_SBIM_SHIFT); + pci_write_config_dword(sii->pcibus, PCI_INT_MASK, w); } - if (PCIE(sih)) - bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, false); + if (PCI(sih)) { + pcicore_pci_setup(sii->pch); + } +} + +/* + * Fixup SROMless PCI device's configuration. + * The current core may be changed upon return. + */ +int ai_pci_fixcfg(struct si_pub *sih) +{ + struct si_info *sii = (struct si_info *)sih; + + /* Fixup PI in SROM shadow area to enable the correct PCI core access */ + /* check 'pi' is correct and fix it if not */ + pcicore_fixcfg(sii->pch); + pcicore_hwup(sii->pch); + return 0; +} + +/* mask&set gpiocontrol bits */ +u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val, u8 priority) +{ + uint regoff; + + regoff = offsetof(struct chipcregs, gpiocontrol); + return ai_cc_reg(sih, regoff, mask, val); +} + +void ai_chipcontrl_epa4331(struct si_pub *sih, bool on) +{ + struct bcma_device *cc; + u32 val; + + cc = ai_findcore(sih, CC_CORE_ID, 0); + + if (on) { + if (ai_get_chippkg(sih) == 9 || ai_get_chippkg(sih) == 0xb) + /* Ext PA Controls for 4331 12x9 Package */ + bcma_set32(cc, CHIPCREGOFFS(chipcontrol), + CCTRL4331_EXTPA_EN | + CCTRL4331_EXTPA_ON_GPIO2_5); + else + /* Ext PA Controls for 4331 12x12 Package */ + bcma_set32(cc, CHIPCREGOFFS(chipcontrol), + CCTRL4331_EXTPA_EN); + } else { + val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5); + bcma_mask32(cc, CHIPCREGOFFS(chipcontrol), + ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5)); + } } /* Enable BT-COEX & Ex-PA for 4313 */ @@ -816,9 +1181,6 @@ bool ai_deviceremoved(struct si_pub *sih) sii = (struct si_info *)sih; - if (sii->icbus->hosttype != BCMA_HOSTTYPE_PCI) - return false; - pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w); if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM) return true; @@ -826,6 +1188,45 @@ bool ai_deviceremoved(struct si_pub *sih) return false; } +bool ai_is_sprom_available(struct si_pub *sih) +{ + struct si_info *sii = (struct si_info *)sih; + + if (ai_get_ccrev(sih) >= 31) { + struct bcma_device *cc; + u32 sromctrl; + + if ((ai_get_cccaps(sih) & CC_CAP_SROM) == 0) + return false; + + cc = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0); + sromctrl = bcma_read32(cc, CHIPCREGOFFS(sromcontrol)); + return sromctrl & SRC_PRESENT; + } + + switch (ai_get_chip_id(sih)) { + case BCM4313_CHIP_ID: + return (sii->chipst & CST4313_SPROM_PRESENT) != 0; + default: + return true; + } +} + +bool ai_is_otp_disabled(struct si_pub *sih) +{ + struct si_info *sii = (struct si_info *)sih; + + switch (ai_get_chip_id(sih)) { + case BCM4313_CHIP_ID: + return (sii->chipst & CST4313_OTP_PRESENT) == 0; + /* These chips always have their OTP on */ + case BCM43224_CHIP_ID: + case BCM43225_CHIP_ID: + default: + return false; + } +} + uint ai_get_buscoretype(struct si_pub *sih) { struct si_info *sii = (struct si_info *)sih; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h index d9f04a683bdb..f84c6f781692 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h @@ -113,6 +113,10 @@ #define XTAL 0x1 /* primary crystal oscillator (2050) */ #define PLL 0x2 /* main chip pll */ +/* clkctl clk mode */ +#define CLK_FAST 0 /* force fast (pll) clock */ +#define CLK_DYNAMIC 2 /* enable dynamic clock control */ + /* GPIO usage priorities */ #define GPIO_DRV_PRIORITY 0 /* Driver */ #define GPIO_APP_PRIORITY 1 /* Application */ @@ -168,7 +172,9 @@ struct si_info { struct si_pub pub; /* back plane public state (must be first) */ struct bcma_bus *icbus; /* handle to soc interconnect bus */ struct pci_dev *pcibus; /* handle to pci bus */ + struct pcicore_info *pch; /* PCI/E core handle */ struct bcma_device *buscore; + struct list_head var_list; /* list of srom variables */ u32 chipst; /* chip status */ }; @@ -191,20 +197,38 @@ extern u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val); extern struct si_pub *ai_attach(struct bcma_bus *pbus); extern void ai_detach(struct si_pub *sih); extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val); +extern void ai_pci_setup(struct si_pub *sih, uint coremask); extern void ai_clkctl_init(struct si_pub *sih); extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih); extern bool ai_clkctl_cc(struct si_pub *sih, uint mode); +extern int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on); extern bool ai_deviceremoved(struct si_pub *sih); +extern u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val, + u8 priority); + +/* OTP status */ +extern bool ai_is_otp_disabled(struct si_pub *sih); + +/* SPROM availability */ +extern bool ai_is_sprom_available(struct si_pub *sih); +extern void ai_pci_sleep(struct si_pub *sih); extern void ai_pci_down(struct si_pub *sih); extern void ai_pci_up(struct si_pub *sih); +extern int ai_pci_fixcfg(struct si_pub *sih); +extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on); /* Enable Ex-PA for 4313 */ extern void ai_epa_4313war(struct si_pub *sih); extern uint ai_get_buscoretype(struct si_pub *sih); extern uint ai_get_buscorerev(struct si_pub *sih); +static inline int ai_get_ccrev(struct si_pub *sih) +{ + return sih->ccrev; +} + static inline u32 ai_get_cccaps(struct si_pub *sih) { return sih->cccaps; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c index 55e12c327911..a47ce25cb9a2 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c @@ -108,7 +108,7 @@ brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel, struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) { struct antsel_info *asi; - struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; + struct si_pub *sih = wlc->hw->sih; asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); if (!asi) @@ -118,7 +118,7 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) asi->pub = wlc->pub; asi->antsel_type = ANTSEL_NA; asi->antsel_avail = false; - asi->antsel_antswitch = sprom->antswitch; + asi->antsel_antswitch = (u8) getintvar(sih, BRCMS_SROM_ANTSWITCH); if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) { switch (asi->antsel_antswitch) { @@ -128,12 +128,12 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) /* 4321/2 board with 2x3 switch logic */ asi->antsel_type = ANTSEL_2x3; /* Antenna selection availability */ - if ((sprom->ant_available_bg == 7) || - (sprom->ant_available_a == 7)) { + if (((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) || + ((u16) getintvar(sih, BRCMS_SROM_AA5G) == 7)) { asi->antsel_avail = true; } else if ( - sprom->ant_available_bg == 3 || - sprom->ant_available_a == 3) { + (u16) getintvar(sih, BRCMS_SROM_AA2G) == 3 || + (u16) getintvar(sih, BRCMS_SROM_AA5G) == 3) { asi->antsel_avail = false; } else { asi->antsel_avail = false; @@ -146,8 +146,8 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) break; } } else if ((asi->pub->sromrev == 4) && - (sprom->ant_available_bg == 7) && - (sprom->ant_available_a == 0)) { + ((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) && + ((u16) getintvar(sih, BRCMS_SROM_AA5G) == 0)) { /* hack to match old 4321CB2 cards with 2of3 antenna switch */ asi->antsel_type = ANTSEL_2x3; asi->antsel_avail = true; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c index eb77ac3cfb6b..0efe88e25a9a 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -1110,7 +1110,7 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) char country_abbrev[BRCM_CNTRY_BUF_SZ]; const struct country_info *country; struct brcms_pub *pub = wlc->pub; - struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; + char *ccode; BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); @@ -1122,8 +1122,9 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) wlc->cmi = wlc_cm; /* store the country code for passing up as a regulatory hint */ - if (sprom->alpha2 && brcms_c_country_valid(sprom->alpha2)) - strncpy(wlc->pub->srom_ccode, sprom->alpha2, sizeof(sprom->alpha2)); + ccode = getvar(wlc->hw->sih, BRCMS_SROM_CCODE); + if (ccode && brcms_c_country_valid(ccode)) + strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1); /* * internal country information which must match diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 50f92a0b7c41..aa15558f75c8 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -25,6 +25,7 @@ #include #include #include +#include "nicpci.h" #include "phy/phy_int.h" #include "d11.h" #include "channel.h" @@ -769,7 +770,7 @@ void brcms_dpc(unsigned long data) * Precondition: Since this function is called in brcms_pci_probe() context, * no locking is required. */ -static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev) +static int brcms_request_fw(struct brcms_info *wl, struct pci_dev *pdev) { int status; struct device *device = &pdev->dev; @@ -1021,7 +1022,7 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) spin_lock_init(&wl->isr_lock); /* prepare ucode */ - if (brcms_request_fw(wl, pdev) < 0) { + if (brcms_request_fw(wl, pdev->bus->host_pci) < 0) { wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); brcms_release_fw(wl); @@ -1042,12 +1043,12 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) wl->pub->ieee_hw = hw; /* register our interrupt handler */ - if (request_irq(pdev->irq, brcms_isr, + if (request_irq(pdev->bus->host_pci->irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); goto fail; } - wl->irq = pdev->irq; + wl->irq = pdev->bus->host_pci->irq; /* register module */ brcms_c_module_register(wl->pub, "linux", wl, NULL); @@ -1097,7 +1098,7 @@ static int __devinit brcms_bcma_probe(struct bcma_device *pdev) dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n", pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class, - pdev->irq); + pdev->bus->host_pci->irq); if ((pdev->id.manuf != BCMA_MANUF_BCM) || (pdev->id.id != BCMA_CORE_80211)) diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c index 19db4052c44c..b4d92792c502 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -1219,7 +1219,7 @@ static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw) } /* control chip clock to save power, enable dynamic clock or force fast clock */ -static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, enum bcma_clkmode mode) +static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode) { if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) { /* new chips with PMU, CCS_FORCEHT will distribute the HT clock @@ -1229,7 +1229,7 @@ static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, enum bcma_clkmode */ if (wlc_hw->clk) { - if (mode == BCMA_CLKMODE_FAST) { + if (mode == CLK_FAST) { bcma_set32(wlc_hw->d11core, D11REGOFFS(clk_ctl_st), CCS_FORCEHT); @@ -1260,7 +1260,7 @@ static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, enum bcma_clkmode ~CCS_FORCEHT); } } - wlc_hw->forcefastclk = (mode == BCMA_CLKMODE_FAST); + wlc_hw->forcefastclk = (mode == CLK_FAST); } else { /* old chips w/o PMU, force HT through cc, @@ -1567,7 +1567,7 @@ void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw) /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); wlc_phy_bw_state_set(wlc_hw->band->pi, bw); @@ -1576,7 +1576,7 @@ void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw) /* restore the clk */ if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC); + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); } static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw) @@ -1882,20 +1882,27 @@ static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw) return true; } -static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ALEN]) +static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw) { - struct ssb_sprom *sprom = &wlc_hw->d11core->bus->sprom; + enum brcms_srom_id var_id = BRCMS_SROM_MACADDR; + char *macaddr; /* If macaddr exists, use it (Sromrev4, CIS, ...). */ - if (!is_zero_ether_addr(sprom->il0mac)) { - memcpy(etheraddr, sprom->il0mac, 6); - return; - } + macaddr = getvar(wlc_hw->sih, var_id); + if (macaddr != NULL) + return macaddr; if (wlc_hw->_nbands > 1) - memcpy(etheraddr, sprom->et1mac, 6); + var_id = BRCMS_SROM_ET1MACADDR; else - memcpy(etheraddr, sprom->il0mac, 6); + var_id = BRCMS_SROM_IL0MACADDR; + + macaddr = getvar(wlc_hw->sih, var_id); + if (macaddr == NULL) + wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr " + "getvar(%d) not found\n", wlc_hw->unit, var_id); + + return macaddr; } /* power both the pll and external oscillator on/off */ @@ -1910,6 +1917,9 @@ static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) if (!want && wlc_hw->pllreq) return; + if (wlc_hw->sih) + ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want); + wlc_hw->sbclk = want; if (!wlc_hw->sbclk) { wlc_hw->clk = false; @@ -1994,7 +2004,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); /* reset the dma engines except first time thru */ if (bcma_core_is_enabled(wlc_hw->d11core)) { @@ -2043,7 +2053,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) brcms_c_mctrl_reset(wlc_hw); if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); brcms_b_phy_reset(wlc_hw); @@ -2055,7 +2065,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) /* restore the clk setting */ if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC); + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); } /* txfifo sizes needs to be modified(increased) since the newer cores @@ -2208,7 +2218,7 @@ static void brcms_c_gpio_init(struct brcms_c_info *wlc) gm |= gc |= BOARD_GPIO_PACTRL; /* apply to gpiocontrol register */ - bcma_chipco_gpio_control(&wlc_hw->d11core->bus->drv_cc, gm, gc); + ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); } static void brcms_ucode_write(struct brcms_hardware *wlc_hw, @@ -3361,7 +3371,7 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) { /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); /* disable interrupts */ macintmask = brcms_intrsoff(wlc->wl); @@ -3395,7 +3405,7 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) { /* restore the clk */ if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC); + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); } static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc, @@ -4426,22 +4436,17 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, uint unit, bool piomode) { struct brcms_hardware *wlc_hw; + char *macaddr = NULL; uint err = 0; uint j; bool wme = false; struct shared_phy_params sha_params; struct wiphy *wiphy = wlc->wiphy; struct pci_dev *pcidev = core->bus->host_pci; - struct ssb_sprom *sprom = &core->bus->sprom; - if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) - BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, - pcidev->vendor, - pcidev->device); - else - BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, - core->bus->boardinfo.vendor, - core->bus->boardinfo.type); + BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, + pcidev->vendor, + pcidev->device); wme = true; @@ -4467,8 +4472,7 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, } /* verify again the device is supported */ - if (core->bus->hosttype == BCMA_HOSTTYPE_PCI && - !brcms_c_chipmatch(pcidev->vendor, pcidev->device)) { + if (!brcms_c_chipmatch(pcidev->vendor, pcidev->device)) { wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported " "vendor/device (0x%x/0x%x)\n", unit, pcidev->vendor, pcidev->device); @@ -4476,13 +4480,8 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, goto fail; } - if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) { - wlc_hw->vendorid = pcidev->vendor; - wlc_hw->deviceid = pcidev->device; - } else { - wlc_hw->vendorid = core->bus->boardinfo.vendor; - wlc_hw->deviceid = core->bus->boardinfo.type; - } + wlc_hw->vendorid = pcidev->vendor; + wlc_hw->deviceid = pcidev->device; wlc_hw->d11core = core; wlc_hw->corerev = core->id.rev; @@ -4502,7 +4501,7 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, * is still false; But it will be called again inside wlc_corereset, * after d11 is out of reset. */ - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); if (!brcms_b_validate_chip_access(wlc_hw)) { @@ -4513,7 +4512,7 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, } /* get the board rev, used just below */ - j = sprom->board_rev; + j = getintvar(wlc_hw->sih, BRCMS_SROM_BOARDREV); /* promote srom boardrev of 0xFF to 1 */ if (j == BOARDREV_PROMOTABLE) j = BOARDREV_PROMOTED; @@ -4526,9 +4525,11 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, err = 15; goto fail; } - wlc_hw->sromrev = sprom->revision; - wlc_hw->boardflags = sprom->boardflags_lo + (sprom->boardflags_hi << 16); - wlc_hw->boardflags2 = sprom->boardflags2_lo + (sprom->boardflags2_hi << 16); + wlc_hw->sromrev = (u8) getintvar(wlc_hw->sih, BRCMS_SROM_REV); + wlc_hw->boardflags = (u32) getintvar(wlc_hw->sih, + BRCMS_SROM_BOARDFLAGS); + wlc_hw->boardflags2 = (u32) getintvar(wlc_hw->sih, + BRCMS_SROM_BOARDFLAGS2); if (wlc_hw->boardflags & BFL_NOPLLDOWN) brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED); @@ -4701,18 +4702,25 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, */ /* init etheraddr state variables */ - brcms_c_get_macaddr(wlc_hw, wlc_hw->etheraddr); - - if (is_broadcast_ether_addr(wlc_hw->etheraddr) || - is_zero_ether_addr(wlc_hw->etheraddr)) { - wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr\n", + macaddr = brcms_c_get_macaddr(wlc_hw); + if (macaddr == NULL) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: macaddr not found\n", unit); + err = 21; + goto fail; + } + if (!mac_pton(macaddr, wlc_hw->etheraddr) || + is_broadcast_ether_addr(wlc_hw->etheraddr) || + is_zero_ether_addr(wlc_hw->etheraddr)) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr %s\n", + unit, macaddr); err = 22; goto fail; } - BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n", - wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih)); + BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", + wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih), + macaddr); return err; @@ -4762,16 +4770,16 @@ static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc) int aa; uint unit; int bandtype; - struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; + struct si_pub *sih = wlc->hw->sih; unit = wlc->pub->unit; bandtype = wlc->band->bandtype; /* get antennas available */ if (bandtype == BRCM_BAND_5G) - aa = sprom->ant_available_a; + aa = (s8) getintvar(sih, BRCMS_SROM_AA5G); else - aa = sprom->ant_available_bg; + aa = (s8) getintvar(sih, BRCMS_SROM_AA2G); if ((aa < 1) || (aa > 15)) { wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in" @@ -4791,9 +4799,9 @@ static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc) /* Compute Antenna Gain */ if (bandtype == BRCM_BAND_5G) - wlc->band->antgain = sprom->antenna_gain.a1; + wlc->band->antgain = (s8) getintvar(sih, BRCMS_SROM_AG1); else - wlc->band->antgain = sprom->antenna_gain.a0; + wlc->band->antgain = (s8) getintvar(sih, BRCMS_SROM_AG0); brcms_c_attach_antgain_init(wlc); @@ -4944,6 +4952,15 @@ static int brcms_b_detach(struct brcms_c_info *wlc) callbacks = 0; + if (wlc_hw->sih) { + /* + * detach interrupt sync mechanism since interrupt is disabled + * and per-port interrupt object may has been freed. this must + * be done before sb core switch + */ + ai_pci_sleep(wlc_hw->sih); + } + brcms_b_detach_dmapio(wlc_hw); band = wlc_hw->band; @@ -5030,7 +5047,9 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw) */ brcms_b_xtal(wlc_hw, ON); ai_clkctl_init(wlc_hw->sih); - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); + + ai_pci_fixcfg(wlc_hw->sih); /* * TODO: test suspend/resume @@ -5059,6 +5078,8 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw) static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) { + uint coremask; + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* @@ -5067,14 +5088,15 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) */ brcms_b_xtal(wlc_hw, ON); ai_clkctl_init(wlc_hw->sih); - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); /* * Configure pci/pcmcia here instead of in brcms_c_attach() * to allow mfg hotswap: down, hotswap (chip power cycle), up. */ - bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci, wlc_hw->d11core, - true); + coremask = (1 << wlc_hw->wlc->core->coreidx); + + ai_pci_setup(wlc_hw->sih, coremask); /* * Need to read the hwradio status here to cover the case where the @@ -5104,7 +5126,7 @@ static int brcms_b_up_finish(struct brcms_hardware *wlc_hw) wlc_phy_hw_state_upd(wlc_hw->band->pi, true); /* FULLY enable dynamic power control and d11 core interrupt */ - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC); + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); brcms_intrson(wlc_hw->wlc->wl); return 0; } @@ -5245,7 +5267,7 @@ static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw) brcms_intrsoff(wlc_hw->wlc->wl); /* ensure we're running on the pll clock again */ - brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); } /* down phy at the last of this stage */ callbacks += wlc_phy_down(wlc_hw->band->pi); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/nicpci.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/nicpci.c new file mode 100644 index 000000000000..7fad6dc19258 --- /dev/null +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/nicpci.c @@ -0,0 +1,826 @@ +/* + * 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. + */ + +#include +#include +#include + +#include +#include +#include +#include "aiutils.h" +#include "pub.h" +#include "nicpci.h" + +/* SPROM offsets */ +#define SRSH_ASPM_OFFSET 4 /* word 4 */ +#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */ +#define SRSH_ASPM_L1_ENB 0x10 /* bit 4 */ +#define SRSH_ASPM_L0s_ENB 0x8 /* bit 3 */ + +#define SRSH_PCIE_MISC_CONFIG 5 /* word 5 */ +#define SRSH_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */ +#define SRSH_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */ +#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */ +#define SRSH_BD_OFFSET 6 /* word 6 */ + +/* chipcontrol */ +#define CHIPCTRL_4321_PLL_DOWN 0x800000/* serdes PLL down override */ + +/* MDIO control */ +#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */ +#define MDIOCTL_DIVISOR_VAL 0x2 +#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */ +#define MDIOCTL_ACCESS_DONE 0x100 /* Transaction complete */ + +/* MDIO Data */ +#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */ +#define MDIODATA_TA 0x00020000 /* Turnaround */ + +#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */ +#define MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */ +#define MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */ +#define MDIODATA_DEVADDR_MASK 0x0f800000 + /* Physmedia devaddr Mask */ + +/* MDIO Data for older revisions < 10 */ +#define MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift */ +#define MDIODATA_REGADDR_MASK_OLD 0x003c0000 + /* Regaddr Mask */ +#define MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift */ +#define MDIODATA_DEVADDR_MASK_OLD 0x0fc00000 + /* Physmedia devaddr Mask */ + +/* Transactions flags */ +#define MDIODATA_WRITE 0x10000000 +#define MDIODATA_READ 0x20000000 +#define MDIODATA_START 0x40000000 + +#define MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */ +#define MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */ + +/* serdes regs (rev < 10) */ +#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */ +#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */ +#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */ + +/* SERDES RX registers */ +#define SERDES_RX_CTRL 1 /* Rx cntrl */ +#define SERDES_RX_TIMER1 2 /* Rx Timer1 */ +#define SERDES_RX_CDR 6 /* CDR */ +#define SERDES_RX_CDRBW 7 /* CDR BW */ +/* SERDES RX control register */ +#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */ +#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */ + +/* SERDES PLL registers */ +#define SERDES_PLL_CTRL 1 /* PLL control reg */ +#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */ + +/* Linkcontrol reg offset in PCIE Cap */ +#define PCIE_CAP_LINKCTRL_OFFSET 16 /* offset in pcie cap */ +#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */ +#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */ +#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */ + +#define PCIE_ASPM_ENAB 3 /* ASPM L0s & L1 in linkctrl */ +#define PCIE_ASPM_L1_ENAB 2 /* ASPM L0s & L1 in linkctrl */ +#define PCIE_ASPM_L0s_ENAB 1 /* ASPM L0s & L1 in linkctrl */ +#define PCIE_ASPM_DISAB 0 /* ASPM L0s & L1 in linkctrl */ + +/* Power management threshold */ +#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */ +#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */ +#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */ +#define PCIE_ASPMTIMER_EXTEND 0x01000000 + /* > rev7: + * enable extend ASPM timer + */ + +/* different register spaces to access thru pcie indirect access */ +#define PCIE_CONFIGREGS 1 /* Access to config space */ +#define PCIE_PCIEREGS 2 /* Access to pcie registers */ + +/* PCIE protocol PHY diagnostic registers */ +#define PCIE_PLP_STATUSREG 0x204 /* Status */ + +/* Status reg PCIE_PLP_STATUSREG */ +#define PCIE_PLP_POLARITYINV_STAT 0x10 + +/* PCIE protocol DLLP diagnostic registers */ +#define PCIE_DLLP_LCREG 0x100 /* Link Control */ +#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */ + +/* PCIE protocol TLP diagnostic registers */ +#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */ + +/* Sonics to PCI translation types */ +#define SBTOPCI_PREF 0x4 /* prefetch enable */ +#define SBTOPCI_BURST 0x8 /* burst enable */ +#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ + +#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */ + +/* PCI core index in SROM shadow area */ +#define SRSH_PI_OFFSET 0 /* first word */ +#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ +#define SRSH_PI_SHIFT 12 /* bit 15:12 */ + +#define PCIREGOFFS(field) offsetof(struct sbpciregs, field) +#define PCIEREGOFFS(field) offsetof(struct sbpcieregs, field) + +/* Sonics side: PCI core and host control registers */ +struct sbpciregs { + u32 control; /* PCI control */ + u32 PAD[3]; + u32 arbcontrol; /* PCI arbiter control */ + u32 clkrun; /* Clkrun Control (>=rev11) */ + u32 PAD[2]; + u32 intstatus; /* Interrupt status */ + u32 intmask; /* Interrupt mask */ + u32 sbtopcimailbox; /* Sonics to PCI mailbox */ + u32 PAD[9]; + u32 bcastaddr; /* Sonics broadcast address */ + u32 bcastdata; /* Sonics broadcast data */ + u32 PAD[2]; + u32 gpioin; /* ro: gpio input (>=rev2) */ + u32 gpioout; /* rw: gpio output (>=rev2) */ + u32 gpioouten; /* rw: gpio output enable (>= rev2) */ + u32 gpiocontrol; /* rw: gpio control (>= rev2) */ + u32 PAD[36]; + u32 sbtopci0; /* Sonics to PCI translation 0 */ + u32 sbtopci1; /* Sonics to PCI translation 1 */ + u32 sbtopci2; /* Sonics to PCI translation 2 */ + u32 PAD[189]; + u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */ + u16 sprom[36]; /* SPROM shadow Area */ + u32 PAD[46]; +}; + +/* SB side: PCIE core and host control registers */ +struct sbpcieregs { + u32 control; /* host mode only */ + u32 PAD[2]; + u32 biststatus; /* bist Status: 0x00C */ + u32 gpiosel; /* PCIE gpio sel: 0x010 */ + u32 gpioouten; /* PCIE gpio outen: 0x14 */ + u32 PAD[2]; + u32 intstatus; /* Interrupt status: 0x20 */ + u32 intmask; /* Interrupt mask: 0x24 */ + u32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */ + u32 PAD[53]; + u32 sbtopcie0; /* sb to pcie translation 0: 0x100 */ + u32 sbtopcie1; /* sb to pcie translation 1: 0x104 */ + u32 sbtopcie2; /* sb to pcie translation 2: 0x108 */ + u32 PAD[5]; + + /* pcie core supports in direct access to config space */ + u32 configaddr; /* pcie config space access: Address field: 0x120 */ + u32 configdata; /* pcie config space access: Data field: 0x124 */ + + /* mdio access to serdes */ + u32 mdiocontrol; /* controls the mdio access: 0x128 */ + u32 mdiodata; /* Data to the mdio access: 0x12c */ + + /* pcie protocol phy/dllp/tlp register indirect access mechanism */ + u32 pcieindaddr; /* indirect access to + * the internal register: 0x130 + */ + u32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */ + + u32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */ + u32 PAD[177]; + u32 pciecfg[4][64]; /* 0x400 - 0x7FF, PCIE Cfg Space */ + u16 sprom[64]; /* SPROM shadow Area */ +}; + +struct pcicore_info { + struct bcma_device *core; + struct si_pub *sih; /* System interconnect handle */ + struct pci_dev *dev; + u8 pciecap_lcreg_offset;/* PCIE capability LCreg offset + * in the config space + */ + bool pcie_pr42767; + u8 pcie_polarity; + u8 pcie_war_aspm_ovr; /* Override ASPM/Clkreq settings */ + + u8 pmecap_offset; /* PM Capability offset in the config space */ + bool pmecap; /* Capable of generating PME */ +}; + +#define PCIE_ASPM(sih) \ + ((ai_get_buscoretype(sih) == PCIE_CORE_ID) && \ + ((ai_get_buscorerev(sih) >= 3) && \ + (ai_get_buscorerev(sih) <= 5))) + + +/* delay needed between the mdio control/ mdiodata register data access */ +static void pr28829_delay(void) +{ + udelay(10); +} + +/* Initialize the PCI core. + * It's caller's responsibility to make sure that this is done only once + */ +struct pcicore_info *pcicore_init(struct si_pub *sih, struct bcma_device *core) +{ + struct pcicore_info *pi; + + /* alloc struct pcicore_info */ + pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC); + if (pi == NULL) + return NULL; + + pi->sih = sih; + pi->dev = core->bus->host_pci; + pi->core = core; + + if (core->id.id == PCIE_CORE_ID) { + u8 cap_ptr; + cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP, + NULL, NULL); + pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET; + } + return pi; +} + +void pcicore_deinit(struct pcicore_info *pch) +{ + kfree(pch); +} + +/* return cap_offset if requested capability exists in the PCI config space */ +/* Note that it's caller's responsibility to make sure it's a pci bus */ +u8 +pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id, + unsigned char *buf, u32 *buflen) +{ + u8 cap_id; + u8 cap_ptr = 0; + u32 bufsize; + u8 byte_val; + + /* check for Header type 0 */ + pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val); + if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL) + goto end; + + /* check if the capability pointer field exists */ + pci_read_config_byte(dev, PCI_STATUS, &byte_val); + if (!(byte_val & PCI_STATUS_CAP_LIST)) + goto end; + + pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr); + /* check if the capability pointer is 0x00 */ + if (cap_ptr == 0x00) + goto end; + + /* loop thru the capability list + * and see if the pcie capability exists + */ + + pci_read_config_byte(dev, cap_ptr, &cap_id); + + while (cap_id != req_cap_id) { + pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr); + if (cap_ptr == 0x00) + break; + pci_read_config_byte(dev, cap_ptr, &cap_id); + } + if (cap_id != req_cap_id) + goto end; + + /* found the caller requested capability */ + if (buf != NULL && buflen != NULL) { + u8 cap_data; + + bufsize = *buflen; + if (!bufsize) + goto end; + *buflen = 0; + /* copy the capability data excluding cap ID and next ptr */ + cap_data = cap_ptr + 2; + if ((bufsize + cap_data) > PCI_SZPCR) + bufsize = PCI_SZPCR - cap_data; + *buflen = bufsize; + while (bufsize--) { + pci_read_config_byte(dev, cap_data, buf); + cap_data++; + buf++; + } + } +end: + return cap_ptr; +} + +/* ***** Register Access API */ +static uint +pcie_readreg(struct bcma_device *core, uint addrtype, uint offset) +{ + uint retval = 0xFFFFFFFF; + + switch (addrtype) { + case PCIE_CONFIGREGS: + bcma_write32(core, PCIEREGOFFS(configaddr), offset); + (void)bcma_read32(core, PCIEREGOFFS(configaddr)); + retval = bcma_read32(core, PCIEREGOFFS(configdata)); + break; + case PCIE_PCIEREGS: + bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset); + (void)bcma_read32(core, PCIEREGOFFS(pcieindaddr)); + retval = bcma_read32(core, PCIEREGOFFS(pcieinddata)); + break; + } + + return retval; +} + +static uint pcie_writereg(struct bcma_device *core, uint addrtype, + uint offset, uint val) +{ + switch (addrtype) { + case PCIE_CONFIGREGS: + bcma_write32(core, PCIEREGOFFS(configaddr), offset); + bcma_write32(core, PCIEREGOFFS(configdata), val); + break; + case PCIE_PCIEREGS: + bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset); + bcma_write32(core, PCIEREGOFFS(pcieinddata), val); + break; + default: + break; + } + return 0; +} + +static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk) +{ + uint mdiodata, i = 0; + uint pcie_serdes_spinwait = 200; + + mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | + (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) | + (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | + (blk << 4)); + bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata); + + pr28829_delay(); + /* retry till the transaction is complete */ + while (i < pcie_serdes_spinwait) { + if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) & + MDIOCTL_ACCESS_DONE) + break; + + udelay(1000); + i++; + } + + if (i >= pcie_serdes_spinwait) + return false; + + return true; +} + +static int +pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write, + uint *val) +{ + uint mdiodata; + uint i = 0; + uint pcie_serdes_spinwait = 10; + + /* enable mdio access to SERDES */ + bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), + MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); + + if (ai_get_buscorerev(pi->sih) >= 10) { + /* new serdes is slower in rw, + * using two layers of reg address mapping + */ + if (!pcie_mdiosetblock(pi, physmedia)) + return 1; + mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) | + (regaddr << MDIODATA_REGADDR_SHF)); + pcie_serdes_spinwait *= 20; + } else { + mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) | + (regaddr << MDIODATA_REGADDR_SHF_OLD)); + } + + if (!write) + mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA); + else + mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | + *val); + + bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata); + + pr28829_delay(); + + /* retry till the transaction is complete */ + while (i < pcie_serdes_spinwait) { + if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) & + MDIOCTL_ACCESS_DONE) { + if (!write) { + pr28829_delay(); + *val = (bcma_read32(pi->core, + PCIEREGOFFS(mdiodata)) & + MDIODATA_MASK); + } + /* Disable mdio access to SERDES */ + bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0); + return 0; + } + udelay(1000); + i++; + } + + /* Timed out. Disable mdio access to SERDES. */ + bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0); + return 1; +} + +/* use the mdio interface to read from mdio slaves */ +static int +pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint regaddr, + uint *regval) +{ + return pcie_mdioop(pi, physmedia, regaddr, false, regval); +} + +/* use the mdio interface to write to mdio slaves */ +static int +pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val) +{ + return pcie_mdioop(pi, physmedia, regaddr, true, &val); +} + +/* ***** Support functions ***** */ +static u8 pcie_clkreq(struct pcicore_info *pi, u32 mask, u32 val) +{ + u32 reg_val; + u8 offset; + + offset = pi->pciecap_lcreg_offset; + if (!offset) + return 0; + + pci_read_config_dword(pi->dev, offset, ®_val); + /* set operation */ + if (mask) { + if (val) + reg_val |= PCIE_CLKREQ_ENAB; + else + reg_val &= ~PCIE_CLKREQ_ENAB; + pci_write_config_dword(pi->dev, offset, reg_val); + pci_read_config_dword(pi->dev, offset, ®_val); + } + if (reg_val & PCIE_CLKREQ_ENAB) + return 1; + else + return 0; +} + +static void pcie_extendL1timer(struct pcicore_info *pi, bool extend) +{ + u32 w; + struct si_pub *sih = pi->sih; + + if (ai_get_buscoretype(sih) != PCIE_CORE_ID || + ai_get_buscorerev(sih) < 7) + return; + + w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); + if (extend) + w |= PCIE_ASPMTIMER_EXTEND; + else + w &= ~PCIE_ASPMTIMER_EXTEND; + pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w); + w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); +} + +/* centralized clkreq control policy */ +static void pcie_clkreq_upd(struct pcicore_info *pi, uint state) +{ + struct si_pub *sih = pi->sih; + + switch (state) { + case SI_DOATTACH: + if (PCIE_ASPM(sih)) + pcie_clkreq(pi, 1, 0); + break; + case SI_PCIDOWN: + /* turn on serdes PLL down */ + if (ai_get_buscorerev(sih) == 6) { + ai_cc_reg(sih, + offsetof(struct chipcregs, chipcontrol_addr), + ~0, 0); + ai_cc_reg(sih, + offsetof(struct chipcregs, chipcontrol_data), + ~0x40, 0); + } else if (pi->pcie_pr42767) { + pcie_clkreq(pi, 1, 1); + } + break; + case SI_PCIUP: + /* turn off serdes PLL down */ + if (ai_get_buscorerev(sih) == 6) { + ai_cc_reg(sih, + offsetof(struct chipcregs, chipcontrol_addr), + ~0, 0); + ai_cc_reg(sih, + offsetof(struct chipcregs, chipcontrol_data), + ~0x40, 0x40); + } else if (PCIE_ASPM(sih)) { /* disable clkreq */ + pcie_clkreq(pi, 1, 0); + } + break; + } +} + +/* ***** PCI core WARs ***** */ +/* Done only once at attach time */ +static void pcie_war_polarity(struct pcicore_info *pi) +{ + u32 w; + + if (pi->pcie_polarity != 0) + return; + + w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_PLP_STATUSREG); + + /* Detect the current polarity at attach and force that polarity and + * disable changing the polarity + */ + if ((w & PCIE_PLP_POLARITYINV_STAT) == 0) + pi->pcie_polarity = SERDES_RX_CTRL_FORCE; + else + pi->pcie_polarity = (SERDES_RX_CTRL_FORCE | + SERDES_RX_CTRL_POLARITY); +} + +/* enable ASPM and CLKREQ if srom doesn't have it */ +/* Needs to happen when update to shadow SROM is needed + * : Coming out of 'standby'/'hibernate' + * : If pcie_war_aspm_ovr state changed + */ +static void pcie_war_aspm_clkreq(struct pcicore_info *pi) +{ + struct si_pub *sih = pi->sih; + u16 val16; + u32 w; + + if (!PCIE_ASPM(sih)) + return; + + /* bypass this on QT or VSIM */ + val16 = bcma_read16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET])); + + val16 &= ~SRSH_ASPM_ENB; + if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB) + val16 |= SRSH_ASPM_ENB; + else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB) + val16 |= SRSH_ASPM_L1_ENB; + else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB) + val16 |= SRSH_ASPM_L0s_ENB; + + bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET]), val16); + + pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w); + w &= ~PCIE_ASPM_ENAB; + w |= pi->pcie_war_aspm_ovr; + pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w); + + val16 = bcma_read16(pi->core, + PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5])); + + if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) { + val16 |= SRSH_CLKREQ_ENB; + pi->pcie_pr42767 = true; + } else + val16 &= ~SRSH_CLKREQ_ENB; + + bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5]), + val16); +} + +/* Apply the polarity determined at the start */ +/* Needs to happen when coming out of 'standby'/'hibernate' */ +static void pcie_war_serdes(struct pcicore_info *pi) +{ + u32 w = 0; + + if (pi->pcie_polarity != 0) + pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL, + pi->pcie_polarity); + + pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w); + if (w & PLL_CTRL_FREQDET_EN) { + w &= ~PLL_CTRL_FREQDET_EN; + pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w); + } +} + +/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */ +/* Needs to happen when coming out of 'standby'/'hibernate' */ +static void pcie_misc_config_fixup(struct pcicore_info *pi) +{ + u16 val16; + + val16 = bcma_read16(pi->core, + PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG])); + + if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) { + val16 |= SRSH_L23READY_EXIT_NOPERST; + bcma_write16(pi->core, + PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG]), val16); + } +} + +/* quick hack for testing */ +/* Needs to happen when coming out of 'standby'/'hibernate' */ +static void pcie_war_noplldown(struct pcicore_info *pi) +{ + /* turn off serdes PLL down */ + ai_cc_reg(pi->sih, offsetof(struct chipcregs, chipcontrol), + CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN); + + /* clear srom shadow backdoor */ + bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_BD_OFFSET]), 0); +} + +/* Needs to happen when coming out of 'standby'/'hibernate' */ +static void pcie_war_pci_setup(struct pcicore_info *pi) +{ + struct si_pub *sih = pi->sih; + u32 w; + + if (ai_get_buscorerev(sih) == 0 || ai_get_buscorerev(sih) == 1) { + w = pcie_readreg(pi->core, PCIE_PCIEREGS, + PCIE_TLP_WORKAROUNDSREG); + w |= 0x8; + pcie_writereg(pi->core, PCIE_PCIEREGS, + PCIE_TLP_WORKAROUNDSREG, w); + } + + if (ai_get_buscorerev(sih) == 1) { + w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG); + w |= 0x40; + pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w); + } + + if (ai_get_buscorerev(sih) == 0) { + pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128); + pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100); + pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466); + } else if (PCIE_ASPM(sih)) { + /* Change the L1 threshold for better performance */ + w = pcie_readreg(pi->core, PCIE_PCIEREGS, + PCIE_DLLP_PMTHRESHREG); + w &= ~PCIE_L1THRESHOLDTIME_MASK; + w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT; + pcie_writereg(pi->core, PCIE_PCIEREGS, + PCIE_DLLP_PMTHRESHREG, w); + + pcie_war_serdes(pi); + + pcie_war_aspm_clkreq(pi); + } else if (ai_get_buscorerev(pi->sih) == 7) + pcie_war_noplldown(pi); + + /* Note that the fix is actually in the SROM, + * that's why this is open-ended + */ + if (ai_get_buscorerev(pi->sih) >= 6) + pcie_misc_config_fixup(pi); +} + +/* ***** Functions called during driver state changes ***** */ +void pcicore_attach(struct pcicore_info *pi, int state) +{ + struct si_pub *sih = pi->sih; + u32 bfl2 = (u32)getintvar(sih, BRCMS_SROM_BOARDFLAGS2); + + /* Determine if this board needs override */ + if (PCIE_ASPM(sih)) { + if (bfl2 & BFL2_PCIEWAR_OVR) + pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB; + else + pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB; + } + + /* These need to happen in this order only */ + pcie_war_polarity(pi); + + pcie_war_serdes(pi); + + pcie_war_aspm_clkreq(pi); + + pcie_clkreq_upd(pi, state); + +} + +void pcicore_hwup(struct pcicore_info *pi) +{ + if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID) + return; + + pcie_war_pci_setup(pi); +} + +void pcicore_up(struct pcicore_info *pi, int state) +{ + if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID) + return; + + /* Restore L1 timer for better performance */ + pcie_extendL1timer(pi, true); + + pcie_clkreq_upd(pi, state); +} + +/* When the device is going to enter D3 state + * (or the system is going to enter S3/S4 states) + */ +void pcicore_sleep(struct pcicore_info *pi) +{ + u32 w; + + if (!pi || !PCIE_ASPM(pi->sih)) + return; + + pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w); + w &= ~PCIE_CAP_LCREG_ASPML1; + pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w); + + pi->pcie_pr42767 = false; +} + +void pcicore_down(struct pcicore_info *pi, int state) +{ + if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID) + return; + + pcie_clkreq_upd(pi, state); + + /* Reduce L1 timer for better power savings */ + pcie_extendL1timer(pi, false); +} + +void pcicore_fixcfg(struct pcicore_info *pi) +{ + struct bcma_device *core = pi->core; + u16 val16; + uint regoff; + + switch (pi->core->id.id) { + case BCMA_CORE_PCI: + regoff = PCIREGOFFS(sprom[SRSH_PI_OFFSET]); + break; + + case BCMA_CORE_PCIE: + regoff = PCIEREGOFFS(sprom[SRSH_PI_OFFSET]); + break; + + default: + return; + } + + val16 = bcma_read16(pi->core, regoff); + if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != + (u16)core->core_index) { + val16 = ((u16)core->core_index << SRSH_PI_SHIFT) | + (val16 & ~SRSH_PI_MASK); + bcma_write16(pi->core, regoff, val16); + } +} + +/* precondition: current core is pci core */ +void +pcicore_pci_setup(struct pcicore_info *pi) +{ + bcma_set32(pi->core, PCIREGOFFS(sbtopci2), + SBTOPCI_PREF | SBTOPCI_BURST); + + if (pi->core->id.rev >= 11) { + bcma_set32(pi->core, PCIREGOFFS(sbtopci2), + SBTOPCI_RC_READMULTI); + bcma_set32(pi->core, PCIREGOFFS(clkrun), PCI_CLKRUN_DSBL); + (void)bcma_read32(pi->core, PCIREGOFFS(clkrun)); + } +} diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/nicpci.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/nicpci.h new file mode 100644 index 000000000000..9fc3ead540a8 --- /dev/null +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/nicpci.h @@ -0,0 +1,77 @@ +/* + * 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 _BRCM_NICPCI_H_ +#define _BRCM_NICPCI_H_ + +#include "types.h" + +/* PCI configuration address space size */ +#define PCI_SZPCR 256 + +/* Brcm PCI configuration registers */ +/* backplane address space accessed by BAR0 */ +#define PCI_BAR0_WIN 0x80 +/* sprom property control */ +#define PCI_SPROM_CONTROL 0x88 +/* mask of PCI and other cores interrupts */ +#define PCI_INT_MASK 0x94 +/* backplane core interrupt mask bits offset */ +#define PCI_SBIM_SHIFT 8 +/* backplane address space accessed by second 4KB of BAR0 */ +#define PCI_BAR0_WIN2 0xac +/* pci config space gpio input (>=rev3) */ +#define PCI_GPIO_IN 0xb0 +/* pci config space gpio output (>=rev3) */ +#define PCI_GPIO_OUT 0xb4 +/* pci config space gpio output enable (>=rev3) */ +#define PCI_GPIO_OUTEN 0xb8 + +/* bar0 + 4K accesses external sprom */ +#define PCI_BAR0_SPROM_OFFSET (4 * 1024) +/* bar0 + 6K accesses pci core registers */ +#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) +/* + * pci core SB registers are at the end of the + * 8KB window, so their address is the "regular" + * address plus 4K + */ +#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) +/* bar0 window size Match with corerev 13 */ +#define PCI_BAR0_WINSZ (16 * 1024) +/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */ +/* bar0 + 8K accesses pci/pcie core registers */ +#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) +/* bar0 + 12K accesses chipc core registers */ +#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) + +struct sbpciregs; +struct sbpcieregs; + +extern struct pcicore_info *pcicore_init(struct si_pub *sih, + struct bcma_device *core); +extern void pcicore_deinit(struct pcicore_info *pch); +extern void pcicore_attach(struct pcicore_info *pch, int state); +extern void pcicore_hwup(struct pcicore_info *pch); +extern void pcicore_up(struct pcicore_info *pch, int state); +extern void pcicore_sleep(struct pcicore_info *pch); +extern void pcicore_down(struct pcicore_info *pch, int state); +extern u8 pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id, + unsigned char *buf, u32 *buflen); +extern void pcicore_fixcfg(struct pcicore_info *pch); +extern void pcicore_pci_setup(struct pcicore_info *pch); + +#endif /* _BRCM_NICPCI_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/otp.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/otp.c new file mode 100644 index 000000000000..f1ca12625860 --- /dev/null +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/otp.c @@ -0,0 +1,410 @@ +/* + * 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. + */ + +#include +#include +#include + +#include +#include +#include "aiutils.h" +#include "otp.h" + +#define OTPS_GUP_MASK 0x00000f00 +#define OTPS_GUP_SHIFT 8 +/* h/w subregion is programmed */ +#define OTPS_GUP_HW 0x00000100 +/* s/w subregion is programmed */ +#define OTPS_GUP_SW 0x00000200 +/* chipid/pkgopt subregion is programmed */ +#define OTPS_GUP_CI 0x00000400 +/* fuse subregion is programmed */ +#define OTPS_GUP_FUSE 0x00000800 + +/* Fields in otpprog in rev >= 21 */ +#define OTPP_COL_MASK 0x000000ff +#define OTPP_COL_SHIFT 0 +#define OTPP_ROW_MASK 0x0000ff00 +#define OTPP_ROW_SHIFT 8 +#define OTPP_OC_MASK 0x0f000000 +#define OTPP_OC_SHIFT 24 +#define OTPP_READERR 0x10000000 +#define OTPP_VALUE_MASK 0x20000000 +#define OTPP_VALUE_SHIFT 29 +#define OTPP_START_BUSY 0x80000000 +#define OTPP_READ 0x40000000 + +/* Opcodes for OTPP_OC field */ +#define OTPPOC_READ 0 +#define OTPPOC_BIT_PROG 1 +#define OTPPOC_VERIFY 3 +#define OTPPOC_INIT 4 +#define OTPPOC_SET 5 +#define OTPPOC_RESET 6 +#define OTPPOC_OCST 7 +#define OTPPOC_ROW_LOCK 8 +#define OTPPOC_PRESCN_TEST 9 + +#define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23) + +#define OTPP_TRIES 10000000 /* # of tries for OTPP */ + +#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */ + +/* Fixed size subregions sizes in words */ +#define OTPGU_CI_SZ 2 + +struct otpinfo; + +/* OTP function struct */ +struct otp_fn_s { + int (*init)(struct si_pub *sih, struct otpinfo *oi); + int (*read_region)(struct otpinfo *oi, int region, u16 *data, + uint *wlen); +}; + +struct otpinfo { + struct bcma_device *core; /* chipc core */ + const struct otp_fn_s *fn; /* OTP functions */ + struct si_pub *sih; /* Saved sb handle */ + + /* IPX OTP section */ + u16 wsize; /* Size of otp in words */ + u16 rows; /* Geometry */ + u16 cols; /* Geometry */ + u32 status; /* Flag bits (lock/prog/rv). + * (Reflected only when OTP is power cycled) + */ + u16 hwbase; /* hardware subregion offset */ + u16 hwlim; /* hardware subregion boundary */ + u16 swbase; /* software subregion offset */ + u16 swlim; /* software subregion boundary */ + u16 fbase; /* fuse subregion offset */ + u16 flim; /* fuse subregion boundary */ + int otpgu_base; /* offset to General Use Region */ +}; + +/* OTP layout */ +/* CC revs 21, 24 and 27 OTP General Use Region word offset */ +#define REVA4_OTPGU_BASE 12 + +/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */ +#define REVB8_OTPGU_BASE 20 + +/* CC rev 36 OTP General Use Region word offset */ +#define REV36_OTPGU_BASE 12 + +/* Subregion word offsets in General Use region */ +#define OTPGU_HSB_OFF 0 +#define OTPGU_SFB_OFF 1 +#define OTPGU_CI_OFF 2 +#define OTPGU_P_OFF 3 +#define OTPGU_SROM_OFF 4 + +/* Flag bit offsets in General Use region */ +#define OTPGU_HWP_OFF 60 +#define OTPGU_SWP_OFF 61 +#define OTPGU_CIP_OFF 62 +#define OTPGU_FUSEP_OFF 63 +#define OTPGU_CIP_MSK 0x4000 +#define OTPGU_P_MSK 0xf000 +#define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16) + +/* OTP Size */ +#define OTP_SZ_FU_324 ((roundup(324, 8))/8) /* 324 bits */ +#define OTP_SZ_FU_288 (288/8) /* 288 bits */ +#define OTP_SZ_FU_216 (216/8) /* 216 bits */ +#define OTP_SZ_FU_72 (72/8) /* 72 bits */ +#define OTP_SZ_CHECKSUM (16/8) /* 16 bits */ +#define OTP4315_SWREG_SZ 178 /* 178 bytes */ +#define OTP_SZ_FU_144 (144/8) /* 144 bits */ + +static u16 +ipxotp_otpr(struct otpinfo *oi, uint wn) +{ + return bcma_read16(oi->core, + CHIPCREGOFFS(sromotp[wn])); +} + +/* + * Calculate max HW/SW region byte size by subtracting fuse region + * and checksum size, osizew is oi->wsize (OTP size - GU size) in words + */ +static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew) +{ + int ret = 0; + + switch (ai_get_chip_id(sih)) { + case BCM43224_CHIP_ID: + case BCM43225_CHIP_ID: + ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM; + break; + case BCM4313_CHIP_ID: + ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM; + break; + default: + break; /* Don't know about this chip */ + } + + return ret; +} + +static void _ipxotp_init(struct otpinfo *oi) +{ + uint k; + u32 otpp, st; + int ccrev = ai_get_ccrev(oi->sih); + + + /* + * record word offset of General Use Region + * for various chipcommon revs + */ + if (ccrev == 21 || ccrev == 24 + || ccrev == 27) { + oi->otpgu_base = REVA4_OTPGU_BASE; + } else if (ccrev == 36) { + /* + * OTP size greater than equal to 2KB (128 words), + * otpgu_base is similar to rev23 + */ + if (oi->wsize >= 128) + oi->otpgu_base = REVB8_OTPGU_BASE; + else + oi->otpgu_base = REV36_OTPGU_BASE; + } else if (ccrev == 23 || ccrev >= 25) { + oi->otpgu_base = REVB8_OTPGU_BASE; + } + + /* First issue an init command so the status is up to date */ + otpp = + OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK); + + bcma_write32(oi->core, CHIPCREGOFFS(otpprog), otpp); + st = bcma_read32(oi->core, CHIPCREGOFFS(otpprog)); + for (k = 0; (st & OTPP_START_BUSY) && (k < OTPP_TRIES); k++) + st = bcma_read32(oi->core, CHIPCREGOFFS(otpprog)); + if (k >= OTPP_TRIES) + return; + + /* Read OTP lock bits and subregion programmed indication bits */ + oi->status = bcma_read32(oi->core, CHIPCREGOFFS(otpstatus)); + + if ((ai_get_chip_id(oi->sih) == BCM43224_CHIP_ID) + || (ai_get_chip_id(oi->sih) == BCM43225_CHIP_ID)) { + u32 p_bits; + p_bits = (ipxotp_otpr(oi, oi->otpgu_base + OTPGU_P_OFF) & + OTPGU_P_MSK) >> OTPGU_P_SHIFT; + oi->status |= (p_bits << OTPS_GUP_SHIFT); + } + + /* + * h/w region base and fuse region limit are fixed to + * the top and the bottom of the general use region. + * Everything else can be flexible. + */ + oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF; + oi->hwlim = oi->wsize; + if (oi->status & OTPS_GUP_HW) { + oi->hwlim = + ipxotp_otpr(oi, oi->otpgu_base + OTPGU_HSB_OFF) / 16; + oi->swbase = oi->hwlim; + } else + oi->swbase = oi->hwbase; + + /* subtract fuse and checksum from beginning */ + oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2; + + if (oi->status & OTPS_GUP_SW) { + oi->swlim = + ipxotp_otpr(oi, oi->otpgu_base + OTPGU_SFB_OFF) / 16; + oi->fbase = oi->swlim; + } else + oi->fbase = oi->swbase; + + oi->flim = oi->wsize; +} + +static int ipxotp_init(struct si_pub *sih, struct otpinfo *oi) +{ + /* Make sure we're running IPX OTP */ + if (!OTPTYPE_IPX(ai_get_ccrev(sih))) + return -EBADE; + + /* Make sure OTP is not disabled */ + if (ai_is_otp_disabled(sih)) + return -EBADE; + + /* Check for otp size */ + switch ((ai_get_cccaps(sih) & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) { + case 0: + /* Nothing there */ + return -EBADE; + case 1: /* 32x64 */ + oi->rows = 32; + oi->cols = 64; + oi->wsize = 128; + break; + case 2: /* 64x64 */ + oi->rows = 64; + oi->cols = 64; + oi->wsize = 256; + break; + case 5: /* 96x64 */ + oi->rows = 96; + oi->cols = 64; + oi->wsize = 384; + break; + case 7: /* 16x64 *//* 1024 bits */ + oi->rows = 16; + oi->cols = 64; + oi->wsize = 64; + break; + default: + /* Don't know the geometry */ + return -EBADE; + } + + /* Retrieve OTP region info */ + _ipxotp_init(oi); + return 0; +} + +static int +ipxotp_read_region(struct otpinfo *oi, int region, u16 *data, uint *wlen) +{ + uint base, i, sz; + + /* Validate region selection */ + switch (region) { + case OTP_HW_RGN: + sz = (uint) oi->hwlim - oi->hwbase; + if (!(oi->status & OTPS_GUP_HW)) { + *wlen = sz; + return -ENODATA; + } + if (*wlen < sz) { + *wlen = sz; + return -EOVERFLOW; + } + base = oi->hwbase; + break; + case OTP_SW_RGN: + sz = ((uint) oi->swlim - oi->swbase); + if (!(oi->status & OTPS_GUP_SW)) { + *wlen = sz; + return -ENODATA; + } + if (*wlen < sz) { + *wlen = sz; + return -EOVERFLOW; + } + base = oi->swbase; + break; + case OTP_CI_RGN: + sz = OTPGU_CI_SZ; + if (!(oi->status & OTPS_GUP_CI)) { + *wlen = sz; + return -ENODATA; + } + if (*wlen < sz) { + *wlen = sz; + return -EOVERFLOW; + } + base = oi->otpgu_base + OTPGU_CI_OFF; + break; + case OTP_FUSE_RGN: + sz = (uint) oi->flim - oi->fbase; + if (!(oi->status & OTPS_GUP_FUSE)) { + *wlen = sz; + return -ENODATA; + } + if (*wlen < sz) { + *wlen = sz; + return -EOVERFLOW; + } + base = oi->fbase; + break; + case OTP_ALL_RGN: + sz = ((uint) oi->flim - oi->hwbase); + if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) { + *wlen = sz; + return -ENODATA; + } + if (*wlen < sz) { + *wlen = sz; + return -EOVERFLOW; + } + base = oi->hwbase; + break; + default: + return -EINVAL; + } + + /* Read the data */ + for (i = 0; i < sz; i++) + data[i] = ipxotp_otpr(oi, base + i); + + *wlen = sz; + return 0; +} + +static const struct otp_fn_s ipxotp_fn = { + (int (*)(struct si_pub *, struct otpinfo *)) ipxotp_init, + (int (*)(struct otpinfo *, int, u16 *, uint *)) ipxotp_read_region, +}; + +static int otp_init(struct si_pub *sih, struct otpinfo *oi) +{ + int ret; + + memset(oi, 0, sizeof(struct otpinfo)); + + oi->core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0); + + if (OTPTYPE_IPX(ai_get_ccrev(sih))) + oi->fn = &ipxotp_fn; + + if (oi->fn == NULL) + return -EBADE; + + oi->sih = sih; + + ret = (oi->fn->init)(sih, oi); + + return ret; +} + +int +otp_read_region(struct si_pub *sih, int region, u16 *data, uint *wlen) { + struct otpinfo otpinfo; + struct otpinfo *oi = &otpinfo; + int err = 0; + + if (ai_is_otp_disabled(sih)) { + err = -EPERM; + goto out; + } + + err = otp_init(sih, oi); + if (err) + goto out; + + err = ((oi)->fn->read_region)(oi, region, data, wlen); + + out: + return err; +} diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/otp.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/otp.h new file mode 100644 index 000000000000..6b6d31cf9569 --- /dev/null +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/otp.h @@ -0,0 +1,36 @@ +/* + * 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 _BRCM_OTP_H_ +#define _BRCM_OTP_H_ + +#include "types.h" + +/* OTP regions */ +#define OTP_HW_RGN 1 +#define OTP_SW_RGN 2 +#define OTP_CI_RGN 4 +#define OTP_FUSE_RGN 8 +/* From h/w region to end of OTP including checksum */ +#define OTP_ALL_RGN 0xf + +/* OTP Size */ +#define OTP_SZ_MAX (6144/8) /* maximum bytes in one CIS */ + +extern int otp_read_region(struct si_pub *sih, int region, u16 *data, + uint *wlen); + +#endif /* _BRCM_OTP_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c index abfd78822fb8..0fce56235f38 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c @@ -4817,23 +4817,28 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) s8 txpwr = 0; int i; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - struct ssb_sprom *sprom = &pi->d11core->bus->sprom; + struct phy_shim_info *shim = pi->sh->physhim; if (CHSPEC_IS2G(pi->radio_chanspec)) { u16 cckpo = 0; u32 offset_ofdm, offset_mcs; - pi_lcn->lcnphy_tr_isolation_mid = sprom->fem.ghz2.tr_iso; + pi_lcn->lcnphy_tr_isolation_mid = + (u8)wlapi_getintvar(shim, BRCMS_SROM_TRISO2G); - pi_lcn->lcnphy_rx_power_offset = sprom->rxpo2g; + pi_lcn->lcnphy_rx_power_offset = + (u8)wlapi_getintvar(shim, BRCMS_SROM_RXPO2G); - pi->txpa_2g[0] = sprom->pa0b0; - pi->txpa_2g[1] = sprom->pa0b1; - pi->txpa_2g[2] = sprom->pa0b2; + pi->txpa_2g[0] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B0); + pi->txpa_2g[1] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B1); + pi->txpa_2g[2] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B2); - pi_lcn->lcnphy_rssi_vf = sprom->rssismf2g; - pi_lcn->lcnphy_rssi_vc = sprom->rssismc2g; - pi_lcn->lcnphy_rssi_gs = sprom->rssisav2g; + pi_lcn->lcnphy_rssi_vf = + (u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISMF2G); + pi_lcn->lcnphy_rssi_vc = + (u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISMC2G); + pi_lcn->lcnphy_rssi_gs = + (u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISAV2G); pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf; pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc; @@ -4843,7 +4848,7 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) pi_lcn->lcnphy_rssi_vc_hightemp = pi_lcn->lcnphy_rssi_vc; pi_lcn->lcnphy_rssi_gs_hightemp = pi_lcn->lcnphy_rssi_gs; - txpwr = sprom->core_pwr_info[0].maxpwr_2g; + txpwr = (s8)wlapi_getintvar(shim, BRCMS_SROM_MAXP2GA0); pi->tx_srom_max_2g = txpwr; for (i = 0; i < PWRTBL_NUM_COEFF; i++) { @@ -4851,8 +4856,8 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) pi->txpa_2g_high_temp[i] = pi->txpa_2g[i]; } - cckpo = sprom->cck2gpo; - offset_ofdm = sprom->ofdm2gpo; + cckpo = (u16)wlapi_getintvar(shim, BRCMS_SROM_CCK2GPO); + offset_ofdm = (u32)wlapi_getintvar(shim, BRCMS_SROM_OFDM2GPO); if (cckpo) { uint max_pwr_chan = txpwr; @@ -4871,7 +4876,7 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) } else { u8 opo = 0; - opo = sprom->opo; + opo = (u8)wlapi_getintvar(shim, BRCMS_SROM_OPO); for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) pi->tx_srom_max_rate_2g[i] = txpwr; @@ -4881,8 +4886,12 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) ((offset_ofdm & 0xf) * 2); offset_ofdm >>= 4; } - offset_mcs = sprom->mcs2gpo[1] << 16; - offset_mcs |= sprom->mcs2gpo[0]; + offset_mcs = + wlapi_getintvar(shim, + BRCMS_SROM_MCS2GPO1) << 16; + offset_mcs |= + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS2GPO0); pi_lcn->lcnphy_mcs20_po = offset_mcs; for (i = TXP_FIRST_SISO_MCS_20; i <= TXP_LAST_SISO_MCS_20; i++) { @@ -4892,17 +4901,25 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) } } - pi_lcn->lcnphy_rawtempsense = sprom->rawtempsense; - pi_lcn->lcnphy_measPower = sprom->measpower; - pi_lcn->lcnphy_tempsense_slope = sprom->tempsense_slope; - pi_lcn->lcnphy_hw_iqcal_en = sprom->hw_iqcal_en; - pi_lcn->lcnphy_iqcal_swp_dis = sprom->iqcal_swp_dis; - pi_lcn->lcnphy_tempcorrx = sprom->tempcorrx; - pi_lcn->lcnphy_tempsense_option = sprom->tempsense_option; - pi_lcn->lcnphy_freqoffset_corr = sprom->freqoffset_corr; - if (sprom->ant_available_bg > 1) + pi_lcn->lcnphy_rawtempsense = + (u16)wlapi_getintvar(shim, BRCMS_SROM_RAWTEMPSENSE); + pi_lcn->lcnphy_measPower = + (u8)wlapi_getintvar(shim, BRCMS_SROM_MEASPOWER); + pi_lcn->lcnphy_tempsense_slope = + (u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPSENSE_SLOPE); + pi_lcn->lcnphy_hw_iqcal_en = + (bool)wlapi_getintvar(shim, BRCMS_SROM_HW_IQCAL_EN); + pi_lcn->lcnphy_iqcal_swp_dis = + (bool)wlapi_getintvar(shim, BRCMS_SROM_IQCAL_SWP_DIS); + pi_lcn->lcnphy_tempcorrx = + (u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPCORRX); + pi_lcn->lcnphy_tempsense_option = + (u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPSENSE_OPTION); + pi_lcn->lcnphy_freqoffset_corr = + (u8)wlapi_getintvar(shim, BRCMS_SROM_FREQOFFSET_CORR); + if ((u8)wlapi_getintvar(shim, BRCMS_SROM_AA2G) > 1) wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi, - sprom->ant_available_bg); + (u8) wlapi_getintvar(shim, BRCMS_SROM_AA2G)); } pi_lcn->lcnphy_cck_dig_filt_type = -1; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index 13b261517cce..812b6e38526e 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c @@ -14386,30 +14386,30 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) { u16 bw40po, cddpo, stbcpo, bwduppo; uint band_num; - struct ssb_sprom *sprom = &pi->d11core->bus->sprom; + struct phy_shim_info *shim = pi->sh->physhim; if (pi->sh->sromrev >= 9) return; - bw40po = sprom->bw40po; + bw40po = (u16) wlapi_getintvar(shim, BRCMS_SROM_BW40PO); pi->bw402gpo = bw40po & 0xf; pi->bw405gpo = (bw40po & 0xf0) >> 4; pi->bw405glpo = (bw40po & 0xf00) >> 8; pi->bw405ghpo = (bw40po & 0xf000) >> 12; - cddpo = sprom->cddpo; + cddpo = (u16) wlapi_getintvar(shim, BRCMS_SROM_CDDPO); pi->cdd2gpo = cddpo & 0xf; pi->cdd5gpo = (cddpo & 0xf0) >> 4; pi->cdd5glpo = (cddpo & 0xf00) >> 8; pi->cdd5ghpo = (cddpo & 0xf000) >> 12; - stbcpo = sprom->stbcpo; + stbcpo = (u16) wlapi_getintvar(shim, BRCMS_SROM_STBCPO); pi->stbc2gpo = stbcpo & 0xf; pi->stbc5gpo = (stbcpo & 0xf0) >> 4; pi->stbc5glpo = (stbcpo & 0xf00) >> 8; pi->stbc5ghpo = (stbcpo & 0xf000) >> 12; - bwduppo = sprom->bwduppo; + bwduppo = (u16) wlapi_getintvar(shim, BRCMS_SROM_BWDUPPO); pi->bwdup2gpo = bwduppo & 0xf; pi->bwdup5gpo = (bwduppo & 0xf0) >> 4; pi->bwdup5glpo = (bwduppo & 0xf00) >> 8; @@ -14419,137 +14419,242 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) band_num++) { switch (band_num) { case 0: + pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g = - sprom->core_pwr_info[0].maxpwr_2g; + (s8) wlapi_getintvar(shim, + BRCMS_SROM_MAXP2GA0); pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g = - sprom->core_pwr_info[1].maxpwr_2g; + (s8) wlapi_getintvar(shim, + BRCMS_SROM_MAXP2GA1); pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 = - sprom->core_pwr_info[0].pa_2g[0]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA2GW0A0); pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 = - sprom->core_pwr_info[1].pa_2g[0]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA2GW0A1); pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 = - sprom->core_pwr_info[0].pa_2g[1]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA2GW1A0); pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 = - sprom->core_pwr_info[1].pa_2g[1]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA2GW1A1); pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 = - sprom->core_pwr_info[0].pa_2g[2]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA2GW2A0); pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 = - sprom->core_pwr_info[1].pa_2g[2]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA2GW2A1); pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g = - sprom->core_pwr_info[0].itssi_2g; + (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT2GA0); pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g = - sprom->core_pwr_info[1].itssi_2g; - - pi->cck2gpo = sprom->cck2gpo; - - pi->ofdm2gpo = sprom->ofdm2gpo; - - pi->mcs2gpo[0] = sprom->mcs2gpo[0]; - pi->mcs2gpo[1] = sprom->mcs2gpo[1]; - pi->mcs2gpo[2] = sprom->mcs2gpo[2]; - pi->mcs2gpo[3] = sprom->mcs2gpo[3]; - pi->mcs2gpo[4] = sprom->mcs2gpo[4]; - pi->mcs2gpo[5] = sprom->mcs2gpo[5]; - pi->mcs2gpo[6] = sprom->mcs2gpo[6]; - pi->mcs2gpo[7] = sprom->mcs2gpo[7]; + (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT2GA1); + + pi->cck2gpo = (u16) wlapi_getintvar(shim, + BRCMS_SROM_CCK2GPO); + + pi->ofdm2gpo = + (u32) wlapi_getintvar(shim, + BRCMS_SROM_OFDM2GPO); + + pi->mcs2gpo[0] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS2GPO0); + pi->mcs2gpo[1] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS2GPO1); + pi->mcs2gpo[2] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS2GPO2); + pi->mcs2gpo[3] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS2GPO3); + pi->mcs2gpo[4] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS2GPO4); + pi->mcs2gpo[5] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS2GPO5); + pi->mcs2gpo[6] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS2GPO6); + pi->mcs2gpo[7] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS2GPO7); break; case 1: pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm = - sprom->core_pwr_info[0].maxpwr_5g; + (s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP5GA0); pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm = - sprom->core_pwr_info[1].maxpwr_5g; + (s8) wlapi_getintvar(shim, + BRCMS_SROM_MAXP5GA1); pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 = - sprom->core_pwr_info[0].pa_5g[0]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GW0A0); pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 = - sprom->core_pwr_info[1].pa_5g[0]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GW0A1); pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 = - sprom->core_pwr_info[0].pa_5g[1]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GW1A0); pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 = - sprom->core_pwr_info[1].pa_5g[1]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GW1A1); pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 = - sprom->core_pwr_info[0].pa_5g[2]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GW2A0); pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 = - sprom->core_pwr_info[1].pa_5g[2]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GW2A1); pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm = - sprom->core_pwr_info[0].itssi_5g; + (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT5GA0); pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm = - sprom->core_pwr_info[1].itssi_5g; - - pi->ofdm5gpo = sprom->ofdm5gpo; - - pi->mcs5gpo[0] = sprom->mcs5gpo[0]; - pi->mcs5gpo[1] = sprom->mcs5gpo[1]; - pi->mcs5gpo[2] = sprom->mcs5gpo[2]; - pi->mcs5gpo[3] = sprom->mcs5gpo[3]; - pi->mcs5gpo[4] = sprom->mcs5gpo[4]; - pi->mcs5gpo[5] = sprom->mcs5gpo[5]; - pi->mcs5gpo[6] = sprom->mcs5gpo[6]; - pi->mcs5gpo[7] = sprom->mcs5gpo[7]; + (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT5GA1); + + pi->ofdm5gpo = + (u32) wlapi_getintvar(shim, + BRCMS_SROM_OFDM5GPO); + + pi->mcs5gpo[0] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GPO0); + pi->mcs5gpo[1] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GPO1); + pi->mcs5gpo[2] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GPO2); + pi->mcs5gpo[3] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GPO3); + pi->mcs5gpo[4] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GPO4); + pi->mcs5gpo[5] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GPO5); + pi->mcs5gpo[6] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GPO6); + pi->mcs5gpo[7] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GPO7); break; case 2: pi->nphy_pwrctrl_info[0].max_pwr_5gl = - sprom->core_pwr_info[0].maxpwr_5gl; + (s8) wlapi_getintvar(shim, + BRCMS_SROM_MAXP5GLA0); pi->nphy_pwrctrl_info[1].max_pwr_5gl = - sprom->core_pwr_info[1].maxpwr_5gl; + (s8) wlapi_getintvar(shim, + BRCMS_SROM_MAXP5GLA1); pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 = - sprom->core_pwr_info[0].pa_5gl[0]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GLW0A0); pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 = - sprom->core_pwr_info[1].pa_5gl[0]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GLW0A1); pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 = - sprom->core_pwr_info[0].pa_5gl[1]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GLW1A0); pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 = - sprom->core_pwr_info[1].pa_5gl[1]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GLW1A1); pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 = - sprom->core_pwr_info[0].pa_5gl[2]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GLW2A0); pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 = - sprom->core_pwr_info[1].pa_5gl[2]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GLW2A1); pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0; pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0; - pi->ofdm5glpo = sprom->ofdm5glpo; - - pi->mcs5glpo[0] = sprom->mcs5glpo[0]; - pi->mcs5glpo[1] = sprom->mcs5glpo[1]; - pi->mcs5glpo[2] = sprom->mcs5glpo[2]; - pi->mcs5glpo[3] = sprom->mcs5glpo[3]; - pi->mcs5glpo[4] = sprom->mcs5glpo[4]; - pi->mcs5glpo[5] = sprom->mcs5glpo[5]; - pi->mcs5glpo[6] = sprom->mcs5glpo[6]; - pi->mcs5glpo[7] = sprom->mcs5glpo[7]; + pi->ofdm5glpo = + (u32) wlapi_getintvar(shim, + BRCMS_SROM_OFDM5GLPO); + + pi->mcs5glpo[0] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GLPO0); + pi->mcs5glpo[1] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GLPO1); + pi->mcs5glpo[2] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GLPO2); + pi->mcs5glpo[3] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GLPO3); + pi->mcs5glpo[4] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GLPO4); + pi->mcs5glpo[5] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GLPO5); + pi->mcs5glpo[6] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GLPO6); + pi->mcs5glpo[7] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GLPO7); break; case 3: pi->nphy_pwrctrl_info[0].max_pwr_5gh = - sprom->core_pwr_info[0].maxpwr_5gh; + (s8) wlapi_getintvar(shim, + BRCMS_SROM_MAXP5GHA0); pi->nphy_pwrctrl_info[1].max_pwr_5gh = - sprom->core_pwr_info[1].maxpwr_5gh; + (s8) wlapi_getintvar(shim, + BRCMS_SROM_MAXP5GHA1); pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 = - sprom->core_pwr_info[0].pa_5gh[0]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GHW0A0); pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 = - sprom->core_pwr_info[1].pa_5gh[0]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GHW0A1); pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 = - sprom->core_pwr_info[0].pa_5gh[1]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GHW1A0); pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 = - sprom->core_pwr_info[1].pa_5gh[1]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GHW1A1); pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 = - sprom->core_pwr_info[0].pa_5gh[2]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GHW2A0); pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 = - sprom->core_pwr_info[1].pa_5gh[2]; + (s16) wlapi_getintvar(shim, + BRCMS_SROM_PA5GHW2A1); pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0; pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0; - pi->ofdm5ghpo = sprom->ofdm5ghpo; - - pi->mcs5ghpo[0] = sprom->mcs5ghpo[0]; - pi->mcs5ghpo[1] = sprom->mcs5ghpo[1]; - pi->mcs5ghpo[2] = sprom->mcs5ghpo[2]; - pi->mcs5ghpo[3] = sprom->mcs5ghpo[3]; - pi->mcs5ghpo[4] = sprom->mcs5ghpo[4]; - pi->mcs5ghpo[5] = sprom->mcs5ghpo[5]; - pi->mcs5ghpo[6] = sprom->mcs5ghpo[6]; - pi->mcs5ghpo[7] = sprom->mcs5ghpo[7]; + pi->ofdm5ghpo = + (u32) wlapi_getintvar(shim, + BRCMS_SROM_OFDM5GHPO); + + pi->mcs5ghpo[0] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GHPO0); + pi->mcs5ghpo[1] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GHPO1); + pi->mcs5ghpo[2] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GHPO2); + pi->mcs5ghpo[3] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GHPO3); + pi->mcs5ghpo[4] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GHPO4); + pi->mcs5ghpo[5] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GHPO5); + pi->mcs5ghpo[6] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GHPO6); + pi->mcs5ghpo[7] = + (u16) wlapi_getintvar(shim, + BRCMS_SROM_MCS5GHPO7); break; } } @@ -14559,34 +14664,45 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi) { - struct ssb_sprom *sprom = &pi->d11core->bus->sprom; - - pi->antswitch = sprom->antswitch; - pi->aa2g = sprom->ant_available_bg; - pi->aa5g = sprom->ant_available_a; - - pi->srom_fem2g.tssipos = sprom->fem.ghz2.tssipos; - pi->srom_fem2g.extpagain = sprom->fem.ghz2.extpa_gain; - pi->srom_fem2g.pdetrange = sprom->fem.ghz2.pdet_range; - pi->srom_fem2g.triso = sprom->fem.ghz2.tr_iso; - pi->srom_fem2g.antswctrllut = sprom->fem.ghz2.antswlut; - - pi->srom_fem5g.tssipos = sprom->fem.ghz5.tssipos; - pi->srom_fem5g.extpagain = sprom->fem.ghz5.extpa_gain; - pi->srom_fem5g.pdetrange = sprom->fem.ghz5.pdet_range; - pi->srom_fem5g.triso = sprom->fem.ghz5.tr_iso; - if (sprom->fem.ghz5.antswlut) - pi->srom_fem5g.antswctrllut = sprom->fem.ghz5.antswlut; + struct phy_shim_info *shim = pi->sh->physhim; + + pi->antswitch = (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWITCH); + pi->aa2g = (u8) wlapi_getintvar(shim, BRCMS_SROM_AA2G); + pi->aa5g = (u8) wlapi_getintvar(shim, BRCMS_SROM_AA5G); + + pi->srom_fem2g.tssipos = (u8) wlapi_getintvar(shim, + BRCMS_SROM_TSSIPOS2G); + pi->srom_fem2g.extpagain = (u8) wlapi_getintvar(shim, + BRCMS_SROM_EXTPAGAIN2G); + pi->srom_fem2g.pdetrange = (u8) wlapi_getintvar(shim, + BRCMS_SROM_PDETRANGE2G); + pi->srom_fem2g.triso = (u8) wlapi_getintvar(shim, BRCMS_SROM_TRISO2G); + pi->srom_fem2g.antswctrllut = + (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL2G); + + pi->srom_fem5g.tssipos = (u8) wlapi_getintvar(shim, + BRCMS_SROM_TSSIPOS5G); + pi->srom_fem5g.extpagain = (u8) wlapi_getintvar(shim, + BRCMS_SROM_EXTPAGAIN5G); + pi->srom_fem5g.pdetrange = (u8) wlapi_getintvar(shim, + BRCMS_SROM_PDETRANGE5G); + pi->srom_fem5g.triso = (u8) wlapi_getintvar(shim, BRCMS_SROM_TRISO5G); + if (wlapi_getvar(shim, BRCMS_SROM_ANTSWCTL5G)) + pi->srom_fem5g.antswctrllut = + (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL5G); else - pi->srom_fem5g.antswctrllut = sprom->fem.ghz2.antswlut; + pi->srom_fem5g.antswctrllut = + (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL2G); wlc_phy_txpower_ipa_upd(pi); - pi->phy_txcore_disable_temp = sprom->tempthresh; + pi->phy_txcore_disable_temp = + (s16) wlapi_getintvar(shim, BRCMS_SROM_TEMPTHRESH); if (pi->phy_txcore_disable_temp == 0) pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP; - pi->phy_tempsense_offset = sprom->tempoffset; + pi->phy_tempsense_offset = (s8) wlapi_getintvar(shim, + BRCMS_SROM_TEMPOFFSET); if (pi->phy_tempsense_offset != 0) { if (pi->phy_tempsense_offset > (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET)) @@ -14601,7 +14717,8 @@ static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi) pi->phy_txcore_enable_temp = pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP; - pi->phycal_tempdelta = sprom->phycal_tempdelta; + pi->phycal_tempdelta = + (u8) wlapi_getintvar(shim, BRCMS_SROM_PHYCAL_TEMPDELTA); if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA) pi->phycal_tempdelta = 0; @@ -21343,7 +21460,7 @@ void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init) write_phy_reg(pi, 0xc8, 0x0); write_phy_reg(pi, 0xc9, 0x0); - bcma_chipco_gpio_control(&pi->d11core->bus->drv_cc, mask, mask); + ai_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY); mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol)); mc &= ~MCTL_GPOUT_SEL_MASK; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c index a0de5db0cd64..5926854f62e2 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c @@ -214,3 +214,12 @@ wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf, { brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel); } + +char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id) +{ + return getvar(physhim->wlc_hw->sih, id); +} +int wlapi_getintvar(struct phy_shim_info *physhim, enum brcms_srom_id id) +{ + return getintvar(physhim->wlc_hw->sih, id); +} diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h index 2c5b66b75970..9168c459b185 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h @@ -175,5 +175,8 @@ extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint, extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim, u32 phy_mode); extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim); +extern char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id); +extern int wlapi_getintvar(struct phy_shim_info *physhim, + enum brcms_srom_id id); #endif /* _BRCM_PHY_SHIM_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h index aa5d67f8d874..f0038ad7d7bf 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h @@ -22,6 +22,232 @@ #include "types.h" #include "defs.h" +enum brcms_srom_id { + BRCMS_SROM_NULL, + BRCMS_SROM_CONT, + BRCMS_SROM_AA2G, + BRCMS_SROM_AA5G, + BRCMS_SROM_AG0, + BRCMS_SROM_AG1, + BRCMS_SROM_AG2, + BRCMS_SROM_AG3, + BRCMS_SROM_ANTSWCTL2G, + BRCMS_SROM_ANTSWCTL5G, + BRCMS_SROM_ANTSWITCH, + BRCMS_SROM_BOARDFLAGS2, + BRCMS_SROM_BOARDFLAGS, + BRCMS_SROM_BOARDNUM, + BRCMS_SROM_BOARDREV, + BRCMS_SROM_BOARDTYPE, + BRCMS_SROM_BW40PO, + BRCMS_SROM_BWDUPPO, + BRCMS_SROM_BXA2G, + BRCMS_SROM_BXA5G, + BRCMS_SROM_CC, + BRCMS_SROM_CCK2GPO, + BRCMS_SROM_CCKBW202GPO, + BRCMS_SROM_CCKBW20UL2GPO, + BRCMS_SROM_CCODE, + BRCMS_SROM_CDDPO, + BRCMS_SROM_DEVID, + BRCMS_SROM_ET1MACADDR, + BRCMS_SROM_EXTPAGAIN2G, + BRCMS_SROM_EXTPAGAIN5G, + BRCMS_SROM_FREQOFFSET_CORR, + BRCMS_SROM_HW_IQCAL_EN, + BRCMS_SROM_IL0MACADDR, + BRCMS_SROM_IQCAL_SWP_DIS, + BRCMS_SROM_LEDBH0, + BRCMS_SROM_LEDBH1, + BRCMS_SROM_LEDBH2, + BRCMS_SROM_LEDBH3, + BRCMS_SROM_LEDDC, + BRCMS_SROM_LEGOFDM40DUPPO, + BRCMS_SROM_LEGOFDMBW202GPO, + BRCMS_SROM_LEGOFDMBW205GHPO, + BRCMS_SROM_LEGOFDMBW205GLPO, + BRCMS_SROM_LEGOFDMBW205GMPO, + BRCMS_SROM_LEGOFDMBW20UL2GPO, + BRCMS_SROM_LEGOFDMBW20UL5GHPO, + BRCMS_SROM_LEGOFDMBW20UL5GLPO, + BRCMS_SROM_LEGOFDMBW20UL5GMPO, + BRCMS_SROM_MACADDR, + BRCMS_SROM_MCS2GPO0, + BRCMS_SROM_MCS2GPO1, + BRCMS_SROM_MCS2GPO2, + BRCMS_SROM_MCS2GPO3, + BRCMS_SROM_MCS2GPO4, + BRCMS_SROM_MCS2GPO5, + BRCMS_SROM_MCS2GPO6, + BRCMS_SROM_MCS2GPO7, + BRCMS_SROM_MCS32PO, + BRCMS_SROM_MCS5GHPO0, + BRCMS_SROM_MCS5GHPO1, + BRCMS_SROM_MCS5GHPO2, + BRCMS_SROM_MCS5GHPO3, + BRCMS_SROM_MCS5GHPO4, + BRCMS_SROM_MCS5GHPO5, + BRCMS_SROM_MCS5GHPO6, + BRCMS_SROM_MCS5GHPO7, + BRCMS_SROM_MCS5GLPO0, + BRCMS_SROM_MCS5GLPO1, + BRCMS_SROM_MCS5GLPO2, + BRCMS_SROM_MCS5GLPO3, + BRCMS_SROM_MCS5GLPO4, + BRCMS_SROM_MCS5GLPO5, + BRCMS_SROM_MCS5GLPO6, + BRCMS_SROM_MCS5GLPO7, + BRCMS_SROM_MCS5GPO0, + BRCMS_SROM_MCS5GPO1, + BRCMS_SROM_MCS5GPO2, + BRCMS_SROM_MCS5GPO3, + BRCMS_SROM_MCS5GPO4, + BRCMS_SROM_MCS5GPO5, + BRCMS_SROM_MCS5GPO6, + BRCMS_SROM_MCS5GPO7, + BRCMS_SROM_MCSBW202GPO, + BRCMS_SROM_MCSBW205GHPO, + BRCMS_SROM_MCSBW205GLPO, + BRCMS_SROM_MCSBW205GMPO, + BRCMS_SROM_MCSBW20UL2GPO, + BRCMS_SROM_MCSBW20UL5GHPO, + BRCMS_SROM_MCSBW20UL5GLPO, + BRCMS_SROM_MCSBW20UL5GMPO, + BRCMS_SROM_MCSBW402GPO, + BRCMS_SROM_MCSBW405GHPO, + BRCMS_SROM_MCSBW405GLPO, + BRCMS_SROM_MCSBW405GMPO, + BRCMS_SROM_MEASPOWER, + BRCMS_SROM_OFDM2GPO, + BRCMS_SROM_OFDM5GHPO, + BRCMS_SROM_OFDM5GLPO, + BRCMS_SROM_OFDM5GPO, + BRCMS_SROM_OPO, + BRCMS_SROM_PA0B0, + BRCMS_SROM_PA0B1, + BRCMS_SROM_PA0B2, + BRCMS_SROM_PA0ITSSIT, + BRCMS_SROM_PA0MAXPWR, + BRCMS_SROM_PA1B0, + BRCMS_SROM_PA1B1, + BRCMS_SROM_PA1B2, + BRCMS_SROM_PA1HIB0, + BRCMS_SROM_PA1HIB1, + BRCMS_SROM_PA1HIB2, + BRCMS_SROM_PA1HIMAXPWR, + BRCMS_SROM_PA1ITSSIT, + BRCMS_SROM_PA1LOB0, + BRCMS_SROM_PA1LOB1, + BRCMS_SROM_PA1LOB2, + BRCMS_SROM_PA1LOMAXPWR, + BRCMS_SROM_PA1MAXPWR, + BRCMS_SROM_PDETRANGE2G, + BRCMS_SROM_PDETRANGE5G, + BRCMS_SROM_PHYCAL_TEMPDELTA, + BRCMS_SROM_RAWTEMPSENSE, + BRCMS_SROM_REGREV, + BRCMS_SROM_REV, + BRCMS_SROM_RSSISAV2G, + BRCMS_SROM_RSSISAV5G, + BRCMS_SROM_RSSISMC2G, + BRCMS_SROM_RSSISMC5G, + BRCMS_SROM_RSSISMF2G, + BRCMS_SROM_RSSISMF5G, + BRCMS_SROM_RXCHAIN, + BRCMS_SROM_RXPO2G, + BRCMS_SROM_RXPO5G, + BRCMS_SROM_STBCPO, + BRCMS_SROM_TEMPCORRX, + BRCMS_SROM_TEMPOFFSET, + BRCMS_SROM_TEMPSENSE_OPTION, + BRCMS_SROM_TEMPSENSE_SLOPE, + BRCMS_SROM_TEMPTHRESH, + BRCMS_SROM_TRI2G, + BRCMS_SROM_TRI5GH, + BRCMS_SROM_TRI5GL, + BRCMS_SROM_TRI5G, + BRCMS_SROM_TRISO2G, + BRCMS_SROM_TRISO5G, + BRCMS_SROM_TSSIPOS2G, + BRCMS_SROM_TSSIPOS5G, + BRCMS_SROM_TXCHAIN, + /* + * per-path identifiers (see srom.c) + */ + BRCMS_SROM_ITT2GA0, + BRCMS_SROM_ITT2GA1, + BRCMS_SROM_ITT2GA2, + BRCMS_SROM_ITT2GA3, + BRCMS_SROM_ITT5GA0, + BRCMS_SROM_ITT5GA1, + BRCMS_SROM_ITT5GA2, + BRCMS_SROM_ITT5GA3, + BRCMS_SROM_MAXP2GA0, + BRCMS_SROM_MAXP2GA1, + BRCMS_SROM_MAXP2GA2, + BRCMS_SROM_MAXP2GA3, + BRCMS_SROM_MAXP5GA0, + BRCMS_SROM_MAXP5GA1, + BRCMS_SROM_MAXP5GA2, + BRCMS_SROM_MAXP5GA3, + BRCMS_SROM_MAXP5GHA0, + BRCMS_SROM_MAXP5GHA1, + BRCMS_SROM_MAXP5GHA2, + BRCMS_SROM_MAXP5GHA3, + BRCMS_SROM_MAXP5GLA0, + BRCMS_SROM_MAXP5GLA1, + BRCMS_SROM_MAXP5GLA2, + BRCMS_SROM_MAXP5GLA3, + BRCMS_SROM_PA2GW0A0, + BRCMS_SROM_PA2GW0A1, + BRCMS_SROM_PA2GW0A2, + BRCMS_SROM_PA2GW0A3, + BRCMS_SROM_PA2GW1A0, + BRCMS_SROM_PA2GW1A1, + BRCMS_SROM_PA2GW1A2, + BRCMS_SROM_PA2GW1A3, + BRCMS_SROM_PA2GW2A0, + BRCMS_SROM_PA2GW2A1, + BRCMS_SROM_PA2GW2A2, + BRCMS_SROM_PA2GW2A3, + BRCMS_SROM_PA5GHW0A0, + BRCMS_SROM_PA5GHW0A1, + BRCMS_SROM_PA5GHW0A2, + BRCMS_SROM_PA5GHW0A3, + BRCMS_SROM_PA5GHW1A0, + BRCMS_SROM_PA5GHW1A1, + BRCMS_SROM_PA5GHW1A2, + BRCMS_SROM_PA5GHW1A3, + BRCMS_SROM_PA5GHW2A0, + BRCMS_SROM_PA5GHW2A1, + BRCMS_SROM_PA5GHW2A2, + BRCMS_SROM_PA5GHW2A3, + BRCMS_SROM_PA5GLW0A0, + BRCMS_SROM_PA5GLW0A1, + BRCMS_SROM_PA5GLW0A2, + BRCMS_SROM_PA5GLW0A3, + BRCMS_SROM_PA5GLW1A0, + BRCMS_SROM_PA5GLW1A1, + BRCMS_SROM_PA5GLW1A2, + BRCMS_SROM_PA5GLW1A3, + BRCMS_SROM_PA5GLW2A0, + BRCMS_SROM_PA5GLW2A1, + BRCMS_SROM_PA5GLW2A2, + BRCMS_SROM_PA5GLW2A3, + BRCMS_SROM_PA5GW0A0, + BRCMS_SROM_PA5GW0A1, + BRCMS_SROM_PA5GW0A2, + BRCMS_SROM_PA5GW0A3, + BRCMS_SROM_PA5GW1A0, + BRCMS_SROM_PA5GW1A1, + BRCMS_SROM_PA5GW1A2, + BRCMS_SROM_PA5GW1A3, + BRCMS_SROM_PA5GW2A0, + BRCMS_SROM_PA5GW2A1, + BRCMS_SROM_PA5GW2A2, + BRCMS_SROM_PA5GW2A3, +}; + #define BRCMS_NUMRATES 16 /* max # of rates in a rateset */ /* phy types */ @@ -339,6 +565,8 @@ extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc, struct ieee80211_sta *sta, u16 tid); extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, u8 ba_wsize, uint max_rx_ampdu_bytes); +extern char *getvar(struct si_pub *sih, enum brcms_srom_id id); +extern int getintvar(struct si_pub *sih, enum brcms_srom_id id); extern int brcms_c_module_register(struct brcms_pub *pub, const char *name, struct brcms_info *hdl, int (*down_fn)(void *handle)); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/srom.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/srom.c new file mode 100644 index 000000000000..b96f4b9d74bd --- /dev/null +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/srom.c @@ -0,0 +1,980 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "pub.h" +#include "nicpci.h" +#include "aiutils.h" +#include "otp.h" +#include "srom.h" +#include "soc.h" + +/* + * SROM CRC8 polynomial value: + * + * x^8 + x^7 +x^6 + x^4 + x^2 + 1 + */ +#define SROM_CRC8_POLY 0xAB + +/* Maximum srom: 6 Kilobits == 768 bytes */ +#define SROM_MAX 768 + +/* PCI fields */ +#define PCI_F0DEVID 48 + +#define SROM_WORDS 64 + +#define SROM_SSID 2 + +#define SROM_WL1LHMAXP 29 + +#define SROM_WL1LPAB0 30 +#define SROM_WL1LPAB1 31 +#define SROM_WL1LPAB2 32 + +#define SROM_WL1HPAB0 33 +#define SROM_WL1HPAB1 34 +#define SROM_WL1HPAB2 35 + +#define SROM_MACHI_IL0 36 +#define SROM_MACMID_IL0 37 +#define SROM_MACLO_IL0 38 +#define SROM_MACHI_ET1 42 +#define SROM_MACMID_ET1 43 +#define SROM_MACLO_ET1 44 + +#define SROM_BXARSSI2G 40 +#define SROM_BXARSSI5G 41 + +#define SROM_TRI52G 42 +#define SROM_TRI5GHL 43 + +#define SROM_RXPO52G 45 + +#define SROM_AABREV 46 +/* Fields in AABREV */ +#define SROM_BR_MASK 0x00ff +#define SROM_CC_MASK 0x0f00 +#define SROM_CC_SHIFT 8 +#define SROM_AA0_MASK 0x3000 +#define SROM_AA0_SHIFT 12 +#define SROM_AA1_MASK 0xc000 +#define SROM_AA1_SHIFT 14 + +#define SROM_WL0PAB0 47 +#define SROM_WL0PAB1 48 +#define SROM_WL0PAB2 49 + +#define SROM_LEDBH10 50 +#define SROM_LEDBH32 51 + +#define SROM_WL10MAXP 52 + +#define SROM_WL1PAB0 53 +#define SROM_WL1PAB1 54 +#define SROM_WL1PAB2 55 + +#define SROM_ITT 56 + +#define SROM_BFL 57 +#define SROM_BFL2 28 + +#define SROM_AG10 58 + +#define SROM_CCODE 59 + +#define SROM_OPO 60 + +#define SROM_CRCREV 63 + +#define SROM4_WORDS 220 + +#define SROM4_TXCHAIN_MASK 0x000f +#define SROM4_RXCHAIN_MASK 0x00f0 +#define SROM4_SWITCH_MASK 0xff00 + +/* Per-path fields */ +#define MAX_PATH_SROM 4 + +#define SROM4_CRCREV 219 + +/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6. + * This is acombined srom for both MIMO and SISO boards, usable in + * the .130 4Kilobit OTP with hardware redundancy. + */ +#define SROM8_BREV 65 + +#define SROM8_BFL0 66 +#define SROM8_BFL1 67 +#define SROM8_BFL2 68 +#define SROM8_BFL3 69 + +#define SROM8_MACHI 70 +#define SROM8_MACMID 71 +#define SROM8_MACLO 72 + +#define SROM8_CCODE 73 +#define SROM8_REGREV 74 + +#define SROM8_LEDBH10 75 +#define SROM8_LEDBH32 76 + +#define SROM8_LEDDC 77 + +#define SROM8_AA 78 + +#define SROM8_AG10 79 +#define SROM8_AG32 80 + +#define SROM8_TXRXC 81 + +#define SROM8_BXARSSI2G 82 +#define SROM8_BXARSSI5G 83 +#define SROM8_TRI52G 84 +#define SROM8_TRI5GHL 85 +#define SROM8_RXPO52G 86 + +#define SROM8_FEM2G 87 +#define SROM8_FEM5G 88 +#define SROM8_FEM_ANTSWLUT_MASK 0xf800 +#define SROM8_FEM_ANTSWLUT_SHIFT 11 +#define SROM8_FEM_TR_ISO_MASK 0x0700 +#define SROM8_FEM_TR_ISO_SHIFT 8 +#define SROM8_FEM_PDET_RANGE_MASK 0x00f8 +#define SROM8_FEM_PDET_RANGE_SHIFT 3 +#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006 +#define SROM8_FEM_EXTPA_GAIN_SHIFT 1 +#define SROM8_FEM_TSSIPOS_MASK 0x0001 +#define SROM8_FEM_TSSIPOS_SHIFT 0 + +#define SROM8_THERMAL 89 + +/* Temp sense related entries */ +#define SROM8_MPWR_RAWTS 90 +#define SROM8_TS_SLP_OPT_CORRX 91 +/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, + * IQSWP: IQ CAL swap disable */ +#define SROM8_FOC_HWIQ_IQSWP 92 + +/* Temperature delta for PHY calibration */ +#define SROM8_PHYCAL_TEMPDELTA 93 + +/* Per-path offsets & fields */ +#define SROM8_PATH0 96 +#define SROM8_PATH1 112 +#define SROM8_PATH2 128 +#define SROM8_PATH3 144 + +#define SROM8_2G_ITT_MAXP 0 +#define SROM8_2G_PA 1 +#define SROM8_5G_ITT_MAXP 4 +#define SROM8_5GLH_MAXP 5 +#define SROM8_5G_PA 6 +#define SROM8_5GL_PA 9 +#define SROM8_5GH_PA 12 + +/* All the miriad power offsets */ +#define SROM8_2G_CCKPO 160 + +#define SROM8_2G_OFDMPO 161 +#define SROM8_5G_OFDMPO 163 +#define SROM8_5GL_OFDMPO 165 +#define SROM8_5GH_OFDMPO 167 + +#define SROM8_2G_MCSPO 169 +#define SROM8_5G_MCSPO 177 +#define SROM8_5GL_MCSPO 185 +#define SROM8_5GH_MCSPO 193 + +#define SROM8_CDDPO 201 +#define SROM8_STBCPO 202 +#define SROM8_BW40PO 203 +#define SROM8_BWDUPPO 204 + +/* SISO PA parameters are in the path0 spaces */ +#define SROM8_SISO 96 + +/* Legacy names for SISO PA paramters */ +#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP) +#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA) +#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1) +#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2) +#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP) +#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP) +#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA) +#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1) +#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2) +#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA) +#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1) +#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2) +#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA) +#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1) +#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2) + +/* SROM REV 9 */ +#define SROM9_2GPO_CCKBW20 160 +#define SROM9_2GPO_CCKBW20UL 161 +#define SROM9_2GPO_LOFDMBW20 162 +#define SROM9_2GPO_LOFDMBW20UL 164 + +#define SROM9_5GLPO_LOFDMBW20 166 +#define SROM9_5GLPO_LOFDMBW20UL 168 +#define SROM9_5GMPO_LOFDMBW20 170 +#define SROM9_5GMPO_LOFDMBW20UL 172 +#define SROM9_5GHPO_LOFDMBW20 174 +#define SROM9_5GHPO_LOFDMBW20UL 176 + +#define SROM9_2GPO_MCSBW20 178 +#define SROM9_2GPO_MCSBW20UL 180 +#define SROM9_2GPO_MCSBW40 182 + +#define SROM9_5GLPO_MCSBW20 184 +#define SROM9_5GLPO_MCSBW20UL 186 +#define SROM9_5GLPO_MCSBW40 188 +#define SROM9_5GMPO_MCSBW20 190 +#define SROM9_5GMPO_MCSBW20UL 192 +#define SROM9_5GMPO_MCSBW40 194 +#define SROM9_5GHPO_MCSBW20 196 +#define SROM9_5GHPO_MCSBW20UL 198 +#define SROM9_5GHPO_MCSBW40 200 + +#define SROM9_PO_MCS32 202 +#define SROM9_PO_LOFDM40DUP 203 + +/* SROM flags (see sromvar_t) */ + +/* value continues as described by the next entry */ +#define SRFL_MORE 1 +#define SRFL_NOFFS 2 /* value bits can't be all one's */ +#define SRFL_PRHEX 4 /* value is in hexdecimal format */ +#define SRFL_PRSIGN 8 /* value is in signed decimal format */ +#define SRFL_CCODE 0x10 /* value is in country code format */ +#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */ +#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */ +/* do not generate a nvram param, entry is for mfgc */ +#define SRFL_NOVAR 0x80 + +/* Max. nvram variable table size */ +#define MAXSZ_NVRAM_VARS 4096 + +/* + * indicates type of value. + */ +enum brcms_srom_var_type { + BRCMS_SROM_STRING, + BRCMS_SROM_SNUMBER, + BRCMS_SROM_UNUMBER +}; + +/* + * storage type for srom variable. + * + * var_list: for linked list operations. + * varid: identifier of the variable. + * var_type: type of variable. + * buf: variable value when var_type == BRCMS_SROM_STRING. + * uval: unsigned variable value when var_type == BRCMS_SROM_UNUMBER. + * sval: signed variable value when var_type == BRCMS_SROM_SNUMBER. + */ +struct brcms_srom_list_head { + struct list_head var_list; + enum brcms_srom_id varid; + enum brcms_srom_var_type var_type; + union { + char buf[0]; + u32 uval; + s32 sval; + }; +}; + +struct brcms_sromvar { + enum brcms_srom_id varid; + u32 revmask; + u32 flags; + u16 off; + u16 mask; +}; + +struct brcms_varbuf { + char *base; /* pointer to buffer base */ + char *buf; /* pointer to current position */ + unsigned int size; /* current (residual) size in bytes */ +}; + +/* + * Assumptions: + * - Ethernet address spans across 3 consecutive words + * + * Table rules: + * - Add multiple entries next to each other if a value spans across multiple + * words (even multiple fields in the same word) with each entry except the + * last having it's SRFL_MORE bit set. + * - Ethernet address entry does not follow above rule and must not have + * SRFL_MORE bit set. Its SRFL_ETHADDR bit implies it takes multiple words. + * - The last entry's name field must be NULL to indicate the end of the table. + * Other entries must have non-NULL name. + */ +static const struct brcms_sromvar pci_sromvars[] = { + {BRCMS_SROM_DEVID, 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, + 0xffff}, + {BRCMS_SROM_BOARDREV, 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff}, + {BRCMS_SROM_BOARDFLAGS, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, + 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM8_BFL1, 0xffff}, + {BRCMS_SROM_BOARDFLAGS2, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, + 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM8_BFL3, 0xffff}, + {BRCMS_SROM_BOARDTYPE, 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff}, + {BRCMS_SROM_BOARDNUM, 0xffffff00, 0, SROM8_MACLO, 0xffff}, + {BRCMS_SROM_REGREV, 0xffffff00, 0, SROM8_REGREV, 0x00ff}, + {BRCMS_SROM_LEDBH0, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff}, + {BRCMS_SROM_LEDBH1, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00}, + {BRCMS_SROM_LEDBH2, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff}, + {BRCMS_SROM_LEDBH3, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00}, + {BRCMS_SROM_PA0B0, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff}, + {BRCMS_SROM_PA0B1, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff}, + {BRCMS_SROM_PA0B2, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff}, + {BRCMS_SROM_PA0ITSSIT, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00}, + {BRCMS_SROM_PA0MAXPWR, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff}, + {BRCMS_SROM_OPO, 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff}, + {BRCMS_SROM_AA2G, 0xffffff00, 0, SROM8_AA, 0x00ff}, + {BRCMS_SROM_AA5G, 0xffffff00, 0, SROM8_AA, 0xff00}, + {BRCMS_SROM_AG0, 0xffffff00, 0, SROM8_AG10, 0x00ff}, + {BRCMS_SROM_AG1, 0xffffff00, 0, SROM8_AG10, 0xff00}, + {BRCMS_SROM_AG2, 0xffffff00, 0, SROM8_AG32, 0x00ff}, + {BRCMS_SROM_AG3, 0xffffff00, 0, SROM8_AG32, 0xff00}, + {BRCMS_SROM_PA1B0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff}, + {BRCMS_SROM_PA1B1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff}, + {BRCMS_SROM_PA1B2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff}, + {BRCMS_SROM_PA1LOB0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff}, + {BRCMS_SROM_PA1LOB1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff}, + {BRCMS_SROM_PA1LOB2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff}, + {BRCMS_SROM_PA1HIB0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff}, + {BRCMS_SROM_PA1HIB1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff}, + {BRCMS_SROM_PA1HIB2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff}, + {BRCMS_SROM_PA1ITSSIT, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00}, + {BRCMS_SROM_PA1MAXPWR, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff}, + {BRCMS_SROM_PA1LOMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00}, + {BRCMS_SROM_PA1HIMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff}, + {BRCMS_SROM_BXA2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800}, + {BRCMS_SROM_RSSISAV2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700}, + {BRCMS_SROM_RSSISMC2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0}, + {BRCMS_SROM_RSSISMF2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f}, + {BRCMS_SROM_BXA5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800}, + {BRCMS_SROM_RSSISAV5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700}, + {BRCMS_SROM_RSSISMC5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0}, + {BRCMS_SROM_RSSISMF5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f}, + {BRCMS_SROM_TRI2G, 0xffffff00, 0, SROM8_TRI52G, 0x00ff}, + {BRCMS_SROM_TRI5G, 0xffffff00, 0, SROM8_TRI52G, 0xff00}, + {BRCMS_SROM_TRI5GL, 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff}, + {BRCMS_SROM_TRI5GH, 0xffffff00, 0, SROM8_TRI5GHL, 0xff00}, + {BRCMS_SROM_RXPO2G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff}, + {BRCMS_SROM_RXPO5G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00}, + {BRCMS_SROM_TXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, + SROM4_TXCHAIN_MASK}, + {BRCMS_SROM_RXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, + SROM4_RXCHAIN_MASK}, + {BRCMS_SROM_ANTSWITCH, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, + SROM4_SWITCH_MASK}, + {BRCMS_SROM_TSSIPOS2G, 0xffffff00, 0, SROM8_FEM2G, + SROM8_FEM_TSSIPOS_MASK}, + {BRCMS_SROM_EXTPAGAIN2G, 0xffffff00, 0, SROM8_FEM2G, + SROM8_FEM_EXTPA_GAIN_MASK}, + {BRCMS_SROM_PDETRANGE2G, 0xffffff00, 0, SROM8_FEM2G, + SROM8_FEM_PDET_RANGE_MASK}, + {BRCMS_SROM_TRISO2G, 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK}, + {BRCMS_SROM_ANTSWCTL2G, 0xffffff00, 0, SROM8_FEM2G, + SROM8_FEM_ANTSWLUT_MASK}, + {BRCMS_SROM_TSSIPOS5G, 0xffffff00, 0, SROM8_FEM5G, + SROM8_FEM_TSSIPOS_MASK}, + {BRCMS_SROM_EXTPAGAIN5G, 0xffffff00, 0, SROM8_FEM5G, + SROM8_FEM_EXTPA_GAIN_MASK}, + {BRCMS_SROM_PDETRANGE5G, 0xffffff00, 0, SROM8_FEM5G, + SROM8_FEM_PDET_RANGE_MASK}, + {BRCMS_SROM_TRISO5G, 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK}, + {BRCMS_SROM_ANTSWCTL5G, 0xffffff00, 0, SROM8_FEM5G, + SROM8_FEM_ANTSWLUT_MASK}, + {BRCMS_SROM_TEMPTHRESH, 0xffffff00, 0, SROM8_THERMAL, 0xff00}, + {BRCMS_SROM_TEMPOFFSET, 0xffffff00, 0, SROM8_THERMAL, 0x00ff}, + + {BRCMS_SROM_CCODE, 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff}, + {BRCMS_SROM_MACADDR, 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff}, + {BRCMS_SROM_LEDDC, 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, + 0xffff}, + {BRCMS_SROM_RAWTEMPSENSE, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, + 0x01ff}, + {BRCMS_SROM_MEASPOWER, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, + 0xfe00}, + {BRCMS_SROM_TEMPSENSE_SLOPE, 0xffffff00, SRFL_PRHEX, + SROM8_TS_SLP_OPT_CORRX, 0x00ff}, + {BRCMS_SROM_TEMPCORRX, 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, + 0xfc00}, + {BRCMS_SROM_TEMPSENSE_OPTION, 0xffffff00, SRFL_PRHEX, + SROM8_TS_SLP_OPT_CORRX, 0x0300}, + {BRCMS_SROM_FREQOFFSET_CORR, 0xffffff00, SRFL_PRHEX, + SROM8_FOC_HWIQ_IQSWP, 0x000f}, + {BRCMS_SROM_IQCAL_SWP_DIS, 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, + 0x0010}, + {BRCMS_SROM_HW_IQCAL_EN, 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, + 0x0020}, + {BRCMS_SROM_PHYCAL_TEMPDELTA, 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, + 0x00ff}, + + {BRCMS_SROM_CCK2GPO, 0x00000100, 0, SROM8_2G_CCKPO, 0xffff}, + {BRCMS_SROM_OFDM2GPO, 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM8_2G_OFDMPO + 1, 0xffff}, + {BRCMS_SROM_OFDM5GPO, 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM8_5G_OFDMPO + 1, 0xffff}, + {BRCMS_SROM_OFDM5GLPO, 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff}, + {BRCMS_SROM_OFDM5GHPO, 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff}, + {BRCMS_SROM_MCS2GPO0, 0x00000100, 0, SROM8_2G_MCSPO, 0xffff}, + {BRCMS_SROM_MCS2GPO1, 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff}, + {BRCMS_SROM_MCS2GPO2, 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff}, + {BRCMS_SROM_MCS2GPO3, 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff}, + {BRCMS_SROM_MCS2GPO4, 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff}, + {BRCMS_SROM_MCS2GPO5, 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff}, + {BRCMS_SROM_MCS2GPO6, 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff}, + {BRCMS_SROM_MCS2GPO7, 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff}, + {BRCMS_SROM_MCS5GPO0, 0x00000100, 0, SROM8_5G_MCSPO, 0xffff}, + {BRCMS_SROM_MCS5GPO1, 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff}, + {BRCMS_SROM_MCS5GPO2, 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff}, + {BRCMS_SROM_MCS5GPO3, 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff}, + {BRCMS_SROM_MCS5GPO4, 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff}, + {BRCMS_SROM_MCS5GPO5, 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff}, + {BRCMS_SROM_MCS5GPO6, 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff}, + {BRCMS_SROM_MCS5GPO7, 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff}, + {BRCMS_SROM_MCS5GLPO0, 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff}, + {BRCMS_SROM_MCS5GLPO1, 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff}, + {BRCMS_SROM_MCS5GLPO2, 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff}, + {BRCMS_SROM_MCS5GLPO3, 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff}, + {BRCMS_SROM_MCS5GLPO4, 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff}, + {BRCMS_SROM_MCS5GLPO5, 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff}, + {BRCMS_SROM_MCS5GLPO6, 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff}, + {BRCMS_SROM_MCS5GLPO7, 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff}, + {BRCMS_SROM_MCS5GHPO0, 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff}, + {BRCMS_SROM_MCS5GHPO1, 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff}, + {BRCMS_SROM_MCS5GHPO2, 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff}, + {BRCMS_SROM_MCS5GHPO3, 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff}, + {BRCMS_SROM_MCS5GHPO4, 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff}, + {BRCMS_SROM_MCS5GHPO5, 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff}, + {BRCMS_SROM_MCS5GHPO6, 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff}, + {BRCMS_SROM_MCS5GHPO7, 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff}, + {BRCMS_SROM_CDDPO, 0x00000100, 0, SROM8_CDDPO, 0xffff}, + {BRCMS_SROM_STBCPO, 0x00000100, 0, SROM8_STBCPO, 0xffff}, + {BRCMS_SROM_BW40PO, 0x00000100, 0, SROM8_BW40PO, 0xffff}, + {BRCMS_SROM_BWDUPPO, 0x00000100, 0, SROM8_BWDUPPO, 0xffff}, + + /* power per rate from sromrev 9 */ + {BRCMS_SROM_CCKBW202GPO, 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff}, + {BRCMS_SROM_CCKBW20UL2GPO, 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff}, + {BRCMS_SROM_LEGOFDMBW202GPO, 0xfffffe00, SRFL_MORE, + SROM9_2GPO_LOFDMBW20, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff}, + {BRCMS_SROM_LEGOFDMBW20UL2GPO, 0xfffffe00, SRFL_MORE, + SROM9_2GPO_LOFDMBW20UL, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff}, + {BRCMS_SROM_LEGOFDMBW205GLPO, 0xfffffe00, SRFL_MORE, + SROM9_5GLPO_LOFDMBW20, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff}, + {BRCMS_SROM_LEGOFDMBW20UL5GLPO, 0xfffffe00, SRFL_MORE, + SROM9_5GLPO_LOFDMBW20UL, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff}, + {BRCMS_SROM_LEGOFDMBW205GMPO, 0xfffffe00, SRFL_MORE, + SROM9_5GMPO_LOFDMBW20, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff}, + {BRCMS_SROM_LEGOFDMBW20UL5GMPO, 0xfffffe00, SRFL_MORE, + SROM9_5GMPO_LOFDMBW20UL, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff}, + {BRCMS_SROM_LEGOFDMBW205GHPO, 0xfffffe00, SRFL_MORE, + SROM9_5GHPO_LOFDMBW20, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff}, + {BRCMS_SROM_LEGOFDMBW20UL5GHPO, 0xfffffe00, SRFL_MORE, + SROM9_5GHPO_LOFDMBW20UL, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff}, + {BRCMS_SROM_MCSBW202GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20, + 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff}, + {BRCMS_SROM_MCSBW20UL2GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL, + 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff}, + {BRCMS_SROM_MCSBW402GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40, + 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff}, + {BRCMS_SROM_MCSBW205GLPO, 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20, + 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff}, + {BRCMS_SROM_MCSBW20UL5GLPO, 0xfffffe00, SRFL_MORE, + SROM9_5GLPO_MCSBW20UL, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff}, + {BRCMS_SROM_MCSBW405GLPO, 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40, + 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff}, + {BRCMS_SROM_MCSBW205GMPO, 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20, + 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff}, + {BRCMS_SROM_MCSBW20UL5GMPO, 0xfffffe00, SRFL_MORE, + SROM9_5GMPO_MCSBW20UL, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff}, + {BRCMS_SROM_MCSBW405GMPO, 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40, + 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff}, + {BRCMS_SROM_MCSBW205GHPO, 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20, + 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff}, + {BRCMS_SROM_MCSBW20UL5GHPO, 0xfffffe00, SRFL_MORE, + SROM9_5GHPO_MCSBW20UL, 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff}, + {BRCMS_SROM_MCSBW405GHPO, 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40, + 0xffff}, + {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff}, + {BRCMS_SROM_MCS32PO, 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff}, + {BRCMS_SROM_LEGOFDM40DUPPO, 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff}, + + {BRCMS_SROM_NULL, 0, 0, 0, 0} +}; + +static const struct brcms_sromvar perpath_pci_sromvars[] = { + {BRCMS_SROM_MAXP2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff}, + {BRCMS_SROM_ITT2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00}, + {BRCMS_SROM_ITT5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00}, + {BRCMS_SROM_PA2GW0A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff}, + {BRCMS_SROM_PA2GW1A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff}, + {BRCMS_SROM_PA2GW2A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff}, + {BRCMS_SROM_MAXP5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff}, + {BRCMS_SROM_MAXP5GHA0, 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff}, + {BRCMS_SROM_MAXP5GLA0, 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00}, + {BRCMS_SROM_PA5GW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff}, + {BRCMS_SROM_PA5GW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff}, + {BRCMS_SROM_PA5GW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff}, + {BRCMS_SROM_PA5GLW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff}, + {BRCMS_SROM_PA5GLW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1, + 0xffff}, + {BRCMS_SROM_PA5GLW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2, + 0xffff}, + {BRCMS_SROM_PA5GHW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff}, + {BRCMS_SROM_PA5GHW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1, + 0xffff}, + {BRCMS_SROM_PA5GHW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2, + 0xffff}, + {BRCMS_SROM_NULL, 0, 0, 0, 0} +}; + +/* crc table has the same contents for every device instance, so it can be + * shared between devices. */ +static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE]; + +static uint mask_shift(u16 mask) +{ + uint i; + for (i = 0; i < (sizeof(mask) << 3); i++) { + if (mask & (1 << i)) + return i; + } + return 0; +} + +static uint mask_width(u16 mask) +{ + int i; + for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) { + if (mask & (1 << i)) + return (uint) (i - mask_shift(mask) + 1); + } + return 0; +} + +static inline void le16_to_cpu_buf(u16 *buf, uint nwords) +{ + while (nwords--) + *(buf + nwords) = le16_to_cpu(*(__le16 *)(buf + nwords)); +} + +static inline void cpu_to_le16_buf(u16 *buf, uint nwords) +{ + while (nwords--) + *(__le16 *)(buf + nwords) = cpu_to_le16(*(buf + nwords)); +} + +/* + * convert binary srom data into linked list of srom variable items. + */ +static int +_initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) +{ + struct brcms_srom_list_head *entry; + enum brcms_srom_id id; + u16 w; + u32 val = 0; + const struct brcms_sromvar *srv; + uint width; + uint flags; + u32 sr = (1 << sromrev); + uint p; + uint pb = SROM8_PATH0; + const uint psz = SROM8_PATH1 - SROM8_PATH0; + + /* first store the srom revision */ + entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL); + if (!entry) + return -ENOMEM; + + entry->varid = BRCMS_SROM_REV; + entry->var_type = BRCMS_SROM_UNUMBER; + entry->uval = sromrev; + list_add(&entry->var_list, var_list); + + for (srv = pci_sromvars; srv->varid != BRCMS_SROM_NULL; srv++) { + enum brcms_srom_var_type type; + u8 ea[ETH_ALEN]; + u8 extra_space = 0; + + if ((srv->revmask & sr) == 0) + continue; + + flags = srv->flags; + id = srv->varid; + + /* This entry is for mfgc only. Don't generate param for it, */ + if (flags & SRFL_NOVAR) + continue; + + if (flags & SRFL_ETHADDR) { + /* + * stored in string format XX:XX:XX:XX:XX:XX (17 chars) + */ + ea[0] = (srom[srv->off] >> 8) & 0xff; + ea[1] = srom[srv->off] & 0xff; + ea[2] = (srom[srv->off + 1] >> 8) & 0xff; + ea[3] = srom[srv->off + 1] & 0xff; + ea[4] = (srom[srv->off + 2] >> 8) & 0xff; + ea[5] = srom[srv->off + 2] & 0xff; + /* 17 characters + string terminator - union size */ + extra_space = 18 - sizeof(s32); + type = BRCMS_SROM_STRING; + } else { + w = srom[srv->off]; + val = (w & srv->mask) >> mask_shift(srv->mask); + width = mask_width(srv->mask); + + while (srv->flags & SRFL_MORE) { + srv++; + if (srv->off == 0) + continue; + + w = srom[srv->off]; + val += + ((w & srv->mask) >> mask_shift(srv-> + mask)) << + width; + width += mask_width(srv->mask); + } + + if ((flags & SRFL_NOFFS) + && ((int)val == (1 << width) - 1)) + continue; + + if (flags & SRFL_CCODE) { + type = BRCMS_SROM_STRING; + } else if (flags & SRFL_LEDDC) { + /* LED Powersave duty cycle has to be scaled: + *(oncount >> 24) (offcount >> 8) + */ + u32 w32 = /* oncount */ + (((val >> 8) & 0xff) << 24) | + /* offcount */ + (((val & 0xff)) << 8); + type = BRCMS_SROM_UNUMBER; + val = w32; + } else if ((flags & SRFL_PRSIGN) + && (val & (1 << (width - 1)))) { + type = BRCMS_SROM_SNUMBER; + val |= ~0 << width; + } else + type = BRCMS_SROM_UNUMBER; + } + + entry = kzalloc(sizeof(struct brcms_srom_list_head) + + extra_space, GFP_KERNEL); + if (!entry) + return -ENOMEM; + entry->varid = id; + entry->var_type = type; + if (flags & SRFL_ETHADDR) { + snprintf(entry->buf, 18, "%pM", ea); + } else if (flags & SRFL_CCODE) { + if (val == 0) + entry->buf[0] = '\0'; + else + snprintf(entry->buf, 3, "%c%c", + (val >> 8), (val & 0xff)); + } else { + entry->uval = val; + } + + list_add(&entry->var_list, var_list); + } + + for (p = 0; p < MAX_PATH_SROM; p++) { + for (srv = perpath_pci_sromvars; + srv->varid != BRCMS_SROM_NULL; srv++) { + if ((srv->revmask & sr) == 0) + continue; + + if (srv->flags & SRFL_NOVAR) + continue; + + w = srom[pb + srv->off]; + val = (w & srv->mask) >> mask_shift(srv->mask); + width = mask_width(srv->mask); + + /* Cheating: no per-path var is more than + * 1 word */ + if ((srv->flags & SRFL_NOFFS) + && ((int)val == (1 << width) - 1)) + continue; + + entry = + kzalloc(sizeof(struct brcms_srom_list_head), + GFP_KERNEL); + if (!entry) + return -ENOMEM; + entry->varid = srv->varid+p; + entry->var_type = BRCMS_SROM_UNUMBER; + entry->uval = val; + list_add(&entry->var_list, var_list); + } + pb += psz; + } + return 0; +} + +/* + * The crc check is done on a little-endian array, we need + * to switch the bytes around before checking crc (and + * then switch it back). + */ +static int do_crc_check(u16 *buf, unsigned nwords) +{ + u8 crc; + + cpu_to_le16_buf(buf, nwords); + crc = crc8(brcms_srom_crc8_table, (void *)buf, nwords << 1, CRC8_INIT_VALUE); + le16_to_cpu_buf(buf, nwords); + + return crc == CRC8_GOOD_VALUE(brcms_srom_crc8_table); +} + +/* + * Read in and validate sprom. + * Return 0 on success, nonzero on error. + */ +static int +sprom_read_pci(struct si_pub *sih, u16 *buf, uint nwords, bool check_crc) +{ + int err = 0; + uint i; + struct bcma_device *core; + uint sprom_offset; + + /* determine core to read */ + if (ai_get_ccrev(sih) < 32) { + core = ai_findcore(sih, BCMA_CORE_80211, 0); + sprom_offset = PCI_BAR0_SPROM_OFFSET; + } else { + core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0); + sprom_offset = CHIPCREGOFFS(sromotp); + } + + /* read the sprom */ + for (i = 0; i < nwords; i++) + buf[i] = bcma_read16(core, sprom_offset+i*2); + + if (buf[0] == 0xffff) + /* + * The hardware thinks that an srom that starts with + * 0xffff is blank, regardless of the rest of the + * content, so declare it bad. + */ + return -ENODATA; + + if (check_crc && !do_crc_check(buf, nwords)) + err = -EIO; + + return err; +} + +static int otp_read_pci(struct si_pub *sih, u16 *buf, uint nwords) +{ + u8 *otp; + uint sz = OTP_SZ_MAX / 2; /* size in words */ + int err = 0; + + otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC); + if (otp == NULL) + return -ENOMEM; + + err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); + + sz = min_t(uint, sz, nwords); + memcpy(buf, otp, sz * 2); + + kfree(otp); + + /* Check CRC */ + if (buf[0] == 0xffff) + /* The hardware thinks that an srom that starts with 0xffff + * is blank, regardless of the rest of the content, so declare + * it bad. + */ + return -ENODATA; + + /* fixup the endianness so crc8 will pass */ + cpu_to_le16_buf(buf, sz); + if (crc8(brcms_srom_crc8_table, (u8 *) buf, sz * 2, + CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(brcms_srom_crc8_table)) + err = -EIO; + else + /* now correct the endianness of the byte array */ + le16_to_cpu_buf(buf, sz); + + return err; +} + +/* + * Initialize nonvolatile variable table from sprom. + * Return 0 on success, nonzero on error. + */ +int srom_var_init(struct si_pub *sih) +{ + u16 *srom; + u8 sromrev = 0; + u32 sr; + int err = 0; + + /* + * Apply CRC over SROM content regardless SROM is present or not. + */ + srom = kmalloc(SROM_MAX, GFP_ATOMIC); + if (!srom) + return -ENOMEM; + + crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY); + if (ai_is_sprom_available(sih)) { + err = sprom_read_pci(sih, srom, SROM4_WORDS, true); + + if (err == 0) + /* srom read and passed crc */ + /* top word of sprom contains version and crc8 */ + sromrev = srom[SROM4_CRCREV] & 0xff; + } else { + /* Use OTP if SPROM not available */ + err = otp_read_pci(sih, srom, SROM4_WORDS); + if (err == 0) + /* OTP only contain SROM rev8/rev9 for now */ + sromrev = srom[SROM4_CRCREV] & 0xff; + } + + if (!err) { + struct si_info *sii = (struct si_info *)sih; + + /* Bitmask for the sromrev */ + sr = 1 << sromrev; + + /* + * srom version check: Current valid versions: 8, 9 + */ + if ((sr & 0x300) == 0) { + err = -EINVAL; + goto errout; + } + + INIT_LIST_HEAD(&sii->var_list); + + /* parse SROM into name=value pairs. */ + err = _initvars_srom_pci(sromrev, srom, &sii->var_list); + if (err) + srom_free_vars(sih); + } + +errout: + kfree(srom); + return err; +} + +void srom_free_vars(struct si_pub *sih) +{ + struct si_info *sii; + struct brcms_srom_list_head *entry, *next; + + sii = (struct si_info *)sih; + list_for_each_entry_safe(entry, next, &sii->var_list, var_list) { + list_del(&entry->var_list); + kfree(entry); + } +} + +/* + * Search the name=value vars for a specific one and return its value. + * Returns NULL if not found. + */ +char *getvar(struct si_pub *sih, enum brcms_srom_id id) +{ + struct si_info *sii; + struct brcms_srom_list_head *entry; + + sii = (struct si_info *)sih; + + list_for_each_entry(entry, &sii->var_list, var_list) + if (entry->varid == id) + return &entry->buf[0]; + + /* nothing found */ + return NULL; +} + +/* + * Search the vars for a specific one and return its value as + * an integer. Returns 0 if not found.- + */ +int getintvar(struct si_pub *sih, enum brcms_srom_id id) +{ + struct si_info *sii; + struct brcms_srom_list_head *entry; + unsigned long res; + + sii = (struct si_info *)sih; + + list_for_each_entry(entry, &sii->var_list, var_list) + if (entry->varid == id) { + if (entry->var_type == BRCMS_SROM_SNUMBER || + entry->var_type == BRCMS_SROM_UNUMBER) + return (int)entry->sval; + else if (!kstrtoul(&entry->buf[0], 0, &res)) + return (int)res; + } + + return 0; +} diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/srom.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/srom.h new file mode 100644 index 000000000000..f2a58f262c99 --- /dev/null +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/srom.h @@ -0,0 +1,29 @@ +/* + * 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 _BRCM_SROM_H_ +#define _BRCM_SROM_H_ + +#include "types.h" + +/* Prototypes */ +extern int srom_var_init(struct si_pub *sih); +extern void srom_free_vars(struct si_pub *sih); + +extern int srom_read(struct si_pub *sih, uint bus, void *curmap, + uint byteoff, uint nbytes, u16 *buf, bool check_crc); + +#endif /* _BRCM_SROM_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c index ed1d1aa71d2d..d8f528eb180c 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c @@ -370,11 +370,9 @@ void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc) void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc) { - struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; - /* get available rx/tx chains */ - wlc->stf->hw_txchain = sprom->txchain; - wlc->stf->hw_rxchain = sprom->rxchain; + wlc->stf->hw_txchain = (u8) getintvar(wlc->hw->sih, BRCMS_SROM_TXCHAIN); + wlc->stf->hw_rxchain = (u8) getintvar(wlc->hw->sih, BRCMS_SROM_RXCHAIN); /* these parameter are intended to be used for all PHY types */ if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index e55ec6c8a920..01dc44267317 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -31,7 +31,6 @@ #include #include #include -#include #include "iwl-dev.h" #include "iwl-io.h" @@ -274,20 +273,9 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) return; } - /* - * Possible situations when BT needs to take over for receive, - * at the same time where STA needs to response to AP's frame(s), - * reduce the tx power of the required response frames, by that, - * allow the concurrent BT receive & WiFi transmit - * (BT - ANT A, WiFi -ANT B), without interference to one another - * - * Reduced tx power apply to control frames only (ACK/Back/CTS) - * when indicated by the BT config command - */ basic.kill_ack_mask = priv->kill_ack_mask; basic.kill_cts_mask = priv->kill_cts_mask; - if (priv->reduced_txpower) - basic.reduce_txpower = IWLAGN_BT_REDUCED_TX_PWR; + basic.reduce_txpower = priv->reduced_txpower; basic.valid = priv->bt_valid; /* @@ -601,31 +589,13 @@ static bool iwlagn_set_kill_msk(struct iwl_priv *priv, return need_update; } -/* - * Upon RSSI changes, sends a bt config command with following changes - * 1. enable/disable "reduced control frames tx power - * 2. update the "kill)ack_mask" and "kill_cts_mask" - * - * If "reduced tx power" is enabled, uCode shall - * 1. ACK/Back/CTS rate shall reduced to 6Mbps - * 2. not use duplciate 20/40MHz mode - */ static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv, struct iwl_bt_uart_msg *uart_msg) { bool need_update = false; - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - int ave_rssi; - ave_rssi = ieee80211_ave_rssi(ctx->vif); - if (!ave_rssi) { - /* no rssi data, no changes to reduce tx power */ - IWL_DEBUG_COEX(priv, "no rssi data available\n"); - return need_update; - } if (!priv->reduced_txpower && !iwl_is_associated(priv, IWL_RXON_CTX_PAN) && - (ave_rssi > BT_ENABLE_REDUCED_TXPOWER_THRESHOLD) && (uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK | BT_UART_MSG_FRAME3OBEX_MSK)) && !(uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK | @@ -636,14 +606,13 @@ static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv, need_update = true; } else if (priv->reduced_txpower && (iwl_is_associated(priv, IWL_RXON_CTX_PAN) || - (ave_rssi < BT_DISABLE_REDUCED_TXPOWER_THRESHOLD) || (uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK | BT_UART_MSG_FRAME3SNIFF_MSK | BT_UART_MSG_FRAME3A2DP_MSK)) || !(uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK | BT_UART_MSG_FRAME3OBEX_MSK)))) { /* disable reduced tx power */ priv->reduced_txpower = false; - priv->bt_valid |= IWLAGN_BT_VALID_REDUCED_TX_PWR; + priv->bt_valid &= ~IWLAGN_BT_VALID_REDUCED_TX_PWR; need_update = true; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 89ccddcf0230..0f7c444f2440 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -61,10 +61,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, RXON_FILTER_ACCEPT_GRP_MSK; break; - case NL80211_IFTYPE_MONITOR: - ctx->staging.dev_type = RXON_DEV_TYPE_SNIFFER; - break; - default: IWL_ERR(priv, "Unsupported interface type %d\n", ctx->vif->type); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 3366e2e2f00f..f2e9f298a947 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -590,17 +590,11 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, spin_unlock_bh(&priv->sta_lock); if (test_bit(txq_id, priv->agg_q_alloc)) { - /* - * If the transport didn't know that we wanted to start - * agreggation, don't tell it that we want to stop them. - * This can happen when we don't get the addBA response on - * time, or we hadn't time to drain the AC queues. + /* If the transport didn't know that we wanted to start + * agreggation, don't tell it that we want to stop them */ - if (agg_state == IWL_AGG_ON) + if (agg_state != IWL_AGG_STARTING) iwl_trans_tx_agg_disable(priv->trans, txq_id); - else - IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", - agg_state); iwlagn_dealloc_agg_txq(priv, txq_id); } @@ -1306,11 +1300,10 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, (u8 *) &ba_resp->sta_addr_lo32, ba_resp->sta_id); IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, " - "scd_flow = %d, scd_ssn = %d sent:%d, acked:%d\n", + "scd_flow = %d, scd_ssn = %d\n", ba_resp->tid, le16_to_cpu(ba_resp->seq_ctl), (unsigned long long)le64_to_cpu(ba_resp->bitmap), - scd_flow, ba_resp_scd_ssn, ba_resp->txed, - ba_resp->txed_2_done); + scd_flow, ba_resp_scd_ssn); /* Mark that the expected block-ack response arrived */ agg->wait_for_ba = false; @@ -1326,6 +1319,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, */ ba_resp->txed = ba_resp->txed_2_done; } + IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n", + ba_resp->txed, ba_resp->txed_2_done); priv->tid_data[sta_id][tid].next_reclaimed = ba_resp_scd_ssn; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c index ec36e2b020b6..8d7637083fcf 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -603,7 +603,7 @@ void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = - BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MONITOR); + BIT(NL80211_IFTYPE_ADHOC); priv->contexts[IWL_RXON_CTX_BSS].interface_modes = BIT(NL80211_IFTYPE_STATION); priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h index 9af6a239b384..83a6930f3658 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -1910,8 +1910,6 @@ enum iwl_bt_kill_idx { IWLAGN_BT_VALID_REDUCED_TX_PWR | \ IWLAGN_BT_VALID_3W_LUT) -#define IWLAGN_BT_REDUCED_TX_PWR BIT(0) - #define IWLAGN_BT_DECISION_LUT_SIZE 12 struct iwl_basic_bt_cmd { @@ -1925,10 +1923,6 @@ struct iwl_basic_bt_cmd { u8 bt3_timer_t2_value; __le16 bt4_reaction_time; /* unused */ __le32 bt3_lookup_table[IWLAGN_BT_DECISION_LUT_SIZE]; - /* - * bit 0: use reduced tx power for control frame - * bit 1 - 7: reserved - */ u8 reduce_txpower; u8 reserved; __le16 valid; @@ -2278,6 +2272,7 @@ struct iwl_ssid_ie { #define IWL_GOOD_CRC_TH_DISABLED 0 #define IWL_GOOD_CRC_TH_DEFAULT cpu_to_le16(1) #define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff) +#define IWL_MAX_SCAN_SIZE 1024 #define IWL_MAX_CMD_SIZE 4096 /* diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c index ab2f4d7500a4..d33cc9cc7d3f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -150,7 +150,6 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, IEEE80211_HW_QUEUE_CONTROL | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | - IEEE80211_HW_WANT_MONITOR_VIF | IEEE80211_HW_SCAN_WHILE_IDLE; hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE; @@ -224,8 +223,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; - /* we create the 802.11 header and a max-length SSID element */ - hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 34; + /* we create the 802.11 header and a zero-length SSID element */ + hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2; /* * We don't use all queues: 4 and 9 are unused and any diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-power.c b/trunk/drivers/net/wireless/iwlwifi/iwl-power.c index 544ddf17f5bd..8352265dbc4b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-power.c @@ -253,8 +253,6 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, IWL_DEBUG_POWER(priv, "numSkipDtim = %u, dtimPeriod = %d\n", skip, period); - /* The power level here is 0-4 (used as array index), but user expects - to see 1-5 (according to spec). */ IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1); } @@ -310,12 +308,10 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, priv->power_data.debug_sleep_level_override, dtimper); else { - /* Note that the user parameter is 1-5 (according to spec), - but we pass 0-4 because it acts as an array index. */ if (iwlwifi_mod_params.power_level > IWL_POWER_INDEX_1 && - iwlwifi_mod_params.power_level <= IWL_POWER_NUM) + iwlwifi_mod_params.power_level <= IWL_POWER_INDEX_5) iwl_static_sleep_cmd(priv, cmd, - iwlwifi_mod_params.power_level - 1, dtimper); + iwlwifi_mod_params.power_level, dtimper); else iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_1, dtimper); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c b/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c index 031d8e21f82f..a8437a6bc18e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -52,7 +52,6 @@ #define IWL_PASSIVE_DWELL_TIME_52 (10) #define IWL_PASSIVE_DWELL_BASE (100) #define IWL_CHANNEL_TUNE_TIME 5 -#define MAX_SCAN_CHANNEL 50 static int iwl_send_scan_abort(struct iwl_priv *priv) { @@ -617,8 +616,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, */ static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta, - const u8 *ies, int ie_len, const u8 *ssid, - u8 ssid_len, int left) + const u8 *ies, int ie_len, int left) { int len = 0; u8 *pos = NULL; @@ -640,18 +638,14 @@ static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta, /* ...next IE... */ pos = &frame->u.probe_req.variable[0]; - /* fill in our SSID IE */ - left -= ssid_len + 2; + /* fill in our indirect SSID IE */ + left -= 2; if (left < 0) return 0; *pos++ = WLAN_EID_SSID; - *pos++ = ssid_len; - if (ssid && ssid_len) { - memcpy(pos, ssid, ssid_len); - pos += ssid_len; - } + *pos++ = 0; - len += ssid_len + 2; + len += 2; if (WARN_ON(left < ie_len)) return len; @@ -685,15 +679,6 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) u8 active_chains; u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; int ret; - int scan_cmd_size = sizeof(struct iwl_scan_cmd) + - MAX_SCAN_CHANNEL * sizeof(struct iwl_scan_channel) + - priv->fw->ucode_capa.max_probe_length; - const u8 *ssid = NULL; - u8 ssid_len = 0; - - if (WARN_ON_ONCE(priv->scan_request && - priv->scan_request->n_channels > MAX_SCAN_CHANNEL)) - return -EINVAL; lockdep_assert_held(&priv->mutex); @@ -701,7 +686,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) ctx = iwl_rxon_ctx_from_vif(vif); if (!priv->scan_cmd) { - priv->scan_cmd = kmalloc(scan_cmd_size, GFP_KERNEL); + priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) + + IWL_MAX_SCAN_SIZE, GFP_KERNEL); if (!priv->scan_cmd) { IWL_DEBUG_SCAN(priv, "fail to allocate memory for scan\n"); @@ -709,7 +695,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) } } scan = priv->scan_cmd; - memset(scan, 0, scan_cmd_size); + memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE); scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; scan->quiet_time = IWL_ACTIVE_QUIET_TIME; @@ -760,18 +746,10 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (priv->scan_request->n_ssids) { int i, p = 0; IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); - /* - * The highest priority SSID is inserted to the - * probe request template. - */ - ssid_len = priv->scan_request->ssids[0].ssid_len; - ssid = priv->scan_request->ssids[0].ssid; - - /* - * Invert the order of ssids, the firmware will invert - * it back. - */ - for (i = priv->scan_request->n_ssids - 1; i >= 1; i--) { + for (i = 0; i < priv->scan_request->n_ssids; i++) { + /* always does wildcard anyway */ + if (!priv->scan_request->ssids[i].ssid_len) + continue; scan->direct_scan[p].id = WLAN_EID_SSID; scan->direct_scan[p].len = priv->scan_request->ssids[i].ssid_len; @@ -905,8 +883,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) vif->addr, priv->scan_request->ie, priv->scan_request->ie_len, - ssid, ssid_len, - scan_cmd_size - sizeof(*scan)); + IWL_MAX_SCAN_SIZE - sizeof(*scan)); break; case IWL_SCAN_RADIO_RESET: case IWL_SCAN_ROC: @@ -914,8 +891,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) cmd_len = iwl_fill_probe_req( (struct ieee80211_mgmt *)scan->data, iwl_bcast_addr, NULL, 0, - NULL, 0, - scan_cmd_size - sizeof(*scan)); + IWL_MAX_SCAN_SIZE - sizeof(*scan)); break; default: BUG(); diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c index fb787df01666..03c0c6b1372c 100644 --- a/trunk/drivers/net/wireless/mac80211_hwsim.c +++ b/trunk/drivers/net/wireless/mac80211_hwsim.c @@ -746,11 +746,6 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) hwsim_check_sta_magic(txi->control.sta); ieee80211_tx_info_clear_status(txi); - - /* frame was transmitted at most favorable rate at first attempt */ - txi->control.rates[0].count = 1; - txi->control.rates[1].idx = -1; - if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack) txi->flags |= IEEE80211_TX_STAT_ACK; ieee80211_tx_status_irqsafe(hw, skb); diff --git a/trunk/drivers/net/wireless/mwifiex/Makefile b/trunk/drivers/net/wireless/mwifiex/Makefile index 3f66ebb0a630..5c1a46bf1e11 100644 --- a/trunk/drivers/net/wireless/mwifiex/Makefile +++ b/trunk/drivers/net/wireless/mwifiex/Makefile @@ -29,8 +29,6 @@ mwifiex-y += scan.o mwifiex-y += join.o mwifiex-y += sta_ioctl.o mwifiex-y += sta_cmd.o -mwifiex-y += uap_cmd.o -mwifiex-y += ie.o mwifiex-y += sta_cmdresp.o mwifiex-y += sta_event.o mwifiex-y += sta_tx.o diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c index 87671446e24b..c78ea873a63a 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c @@ -20,23 +20,6 @@ #include "cfg80211.h" #include "main.h" -static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = { - { - .max = 1, .types = BIT(NL80211_IFTYPE_STATION), - }, - { - .max = 1, .types = BIT(NL80211_IFTYPE_AP), - }, -}; - -static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = { - .limits = mwifiex_ap_sta_limits, - .num_different_channels = 1, - .n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits), - .max_interfaces = MWIFIEX_MAX_BSS_NUM, - .beacon_int_infra_match = true, -}; - /* * This function maps the nl802.11 channel type into driver channel type. * @@ -84,7 +67,7 @@ mwifiex_is_alg_wep(u32 cipher) /* * This function retrieves the private structure from kernel wiphy structure. */ -static void *mwifiex_cfg80211_get_adapter(struct wiphy *wiphy) +static void *mwifiex_cfg80211_get_priv(struct wiphy *wiphy) { return (void *) (*(unsigned long *) wiphy_priv(wiphy)); } @@ -97,10 +80,8 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); - const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - const u8 *peer_mac = pairwise ? mac_addr : bc_mac; - if (mwifiex_set_encode(priv, NULL, 0, key_index, peer_mac, 1)) { + if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) { wiphy_err(wiphy, "deleting the crypto keys\n"); return -EFAULT; } @@ -117,8 +98,7 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int mbm) { - struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); - struct mwifiex_private *priv; + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); struct mwifiex_power_cfg power_cfg; int dbm = MBM_TO_DBM(mbm); @@ -129,8 +109,6 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, power_cfg.is_power_auto = 1; } - priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); - return mwifiex_set_tx_power(priv, &power_cfg); } @@ -170,7 +148,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, if (!priv->sec_info.wep_enabled) return 0; - if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) { + if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) { wiphy_err(wiphy, "set default Tx key index\n"); return -EFAULT; } @@ -187,11 +165,9 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, struct key_params *params) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); - const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - const u8 *peer_mac = pairwise ? mac_addr : bc_mac; if (mwifiex_set_encode(priv, params->key, params->key_len, - key_index, peer_mac, 0)) { + key_index, 0)) { wiphy_err(wiphy, "crypto keys added\n"); return -EFAULT; } @@ -216,13 +192,13 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) enum ieee80211_band band; struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; - struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); - struct mwifiex_private *priv; + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg; /* Set country code */ - domain_info->country_code[0] = adapter->country_code[0]; - domain_info->country_code[1] = adapter->country_code[1]; + domain_info->country_code[0] = priv->country_code[0]; + domain_info->country_code[1] = priv->country_code[1]; domain_info->country_code[2] = ' '; band = mwifiex_band_to_radio_type(adapter->config_bands); @@ -274,8 +250,6 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) domain_info->no_of_triplet = no_of_triplet; - priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); - if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, HostCmd_ACT_GEN_SET, 0, NULL)) { wiphy_err(wiphy, "11D: setting domain info in FW\n"); @@ -298,12 +272,12 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) static int mwifiex_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) { - struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); - wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for %c%c\n", - request->alpha2[0], request->alpha2[1]); + wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for domain" + " %c%c\n", request->alpha2[0], request->alpha2[1]); - memcpy(adapter->country_code, request->alpha2, sizeof(request->alpha2)); + memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2)); switch (request->initiator) { case NL80211_REGDOM_SET_BY_DRIVER: @@ -387,10 +361,33 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, if (mwifiex_bss_set_channel(priv, &cfp)) return -EFAULT; - if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) - return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); + return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); +} + +/* + * CFG802.11 operation handler to set channel. + * + * This function can only be used when station is not connected. + */ +static int +mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type) +{ + struct mwifiex_private *priv; + + if (dev) + priv = mwifiex_netdev_get_priv(dev); else - return mwifiex_uap_set_channel(priv, cfp.channel); + priv = mwifiex_cfg80211_get_priv(wiphy); + + if (priv->media_connected) { + wiphy_err(wiphy, "This setting is valid only when station " + "is not connected\n"); + return -EINVAL; + } + + return mwifiex_set_rf_channel(priv, chan, channel_type); } /* @@ -402,13 +399,18 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, static int mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) { + int ret; + if (frag_thr < MWIFIEX_FRAG_MIN_VALUE || frag_thr > MWIFIEX_FRAG_MAX_VALUE) - frag_thr = MWIFIEX_FRAG_MAX_VALUE; + return -EINVAL; - return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, - HostCmd_ACT_GEN_SET, FRAG_THRESH_I, - &frag_thr); + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_SET, FRAG_THRESH_I, + &frag_thr); + + return ret; } /* @@ -437,85 +439,19 @@ mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) static int mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) { - struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); - struct mwifiex_private *priv; - struct mwifiex_uap_bss_param *bss_cfg; - int ret, bss_started, i; - - for (i = 0; i < adapter->priv_num; i++) { - priv = adapter->priv[i]; - - switch (priv->bss_role) { - case MWIFIEX_BSS_ROLE_UAP: - bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), - GFP_KERNEL); - if (!bss_cfg) - return -ENOMEM; - - mwifiex_set_sys_config_invalid_data(bss_cfg); - - if (changed & WIPHY_PARAM_RTS_THRESHOLD) - bss_cfg->rts_threshold = wiphy->rts_threshold; - if (changed & WIPHY_PARAM_FRAG_THRESHOLD) - bss_cfg->frag_threshold = wiphy->frag_threshold; - if (changed & WIPHY_PARAM_RETRY_LONG) - bss_cfg->retry_limit = wiphy->retry_long; - - bss_started = priv->bss_started; - - ret = mwifiex_send_cmd_sync(priv, - HostCmd_CMD_UAP_BSS_STOP, - HostCmd_ACT_GEN_SET, 0, - NULL); - if (ret) { - wiphy_err(wiphy, "Failed to stop the BSS\n"); - kfree(bss_cfg); - return ret; - } - - ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_UAP_SYS_CONFIG, - HostCmd_ACT_GEN_SET, - UAP_BSS_PARAMS_I, bss_cfg); - - kfree(bss_cfg); - - if (ret) { - wiphy_err(wiphy, "Failed to set bss config\n"); - return ret; - } - - if (!bss_started) - break; - - ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_UAP_BSS_START, - HostCmd_ACT_GEN_SET, 0, - NULL); - if (ret) { - wiphy_err(wiphy, "Failed to start BSS\n"); - return ret; - } + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + int ret = 0; - break; - case MWIFIEX_BSS_ROLE_STA: - if (changed & WIPHY_PARAM_RTS_THRESHOLD) { - ret = mwifiex_set_rts(priv, - wiphy->rts_threshold); - if (ret) - return ret; - } - if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { - ret = mwifiex_set_frag(priv, - wiphy->frag_threshold); - if (ret) - return ret; - } - break; - } + if (changed & WIPHY_PARAM_RTS_THRESHOLD) { + ret = mwifiex_set_rts(priv, wiphy->rts_threshold); + if (ret) + return ret; } - return 0; + if (changed & WIPHY_PARAM_FRAG_THRESHOLD) + ret = mwifiex_set_frag(priv, wiphy->frag_threshold); + + return ret; } /* @@ -530,59 +466,31 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, int ret; struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - switch (dev->ieee80211_ptr->iftype) { + if (priv->bss_mode == type) { + wiphy_warn(wiphy, "already set to required type\n"); + return 0; + } + + priv->bss_mode = type; + + switch (type) { case NL80211_IFTYPE_ADHOC: - switch (type) { - case NL80211_IFTYPE_STATION: - break; - case NL80211_IFTYPE_UNSPECIFIED: - wiphy_warn(wiphy, "%s: kept type as IBSS\n", dev->name); - case NL80211_IFTYPE_ADHOC: /* This shouldn't happen */ - return 0; - case NL80211_IFTYPE_AP: - default: - wiphy_err(wiphy, "%s: changing to %d not supported\n", - dev->name, type); - return -EOPNOTSUPP; - } + dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC; + wiphy_dbg(wiphy, "info: setting interface type to adhoc\n"); break; case NL80211_IFTYPE_STATION: - switch (type) { - case NL80211_IFTYPE_ADHOC: - break; - case NL80211_IFTYPE_UNSPECIFIED: - wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name); - case NL80211_IFTYPE_STATION: /* This shouldn't happen */ - return 0; - case NL80211_IFTYPE_AP: - default: - wiphy_err(wiphy, "%s: changing to %d not supported\n", - dev->name, type); - return -EOPNOTSUPP; - } - break; - case NL80211_IFTYPE_AP: - switch (type) { - case NL80211_IFTYPE_UNSPECIFIED: - wiphy_warn(wiphy, "%s: kept type as AP\n", dev->name); - case NL80211_IFTYPE_AP: /* This shouldn't happen */ - return 0; - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_STATION: - default: - wiphy_err(wiphy, "%s: changing to %d not supported\n", - dev->name, type); - return -EOPNOTSUPP; - } + dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; + wiphy_dbg(wiphy, "info: setting interface type to managed\n"); break; + case NL80211_IFTYPE_UNSPECIFIED: + dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; + wiphy_dbg(wiphy, "info: setting interface type to auto\n"); + return 0; default: - wiphy_err(wiphy, "%s: unknown iftype: %d\n", - dev->name, dev->ieee80211_ptr->iftype); - return -EOPNOTSUPP; + wiphy_err(wiphy, "unknown interface type: %d\n", type); + return -EINVAL; } - dev->ieee80211_ptr->iftype = type; - priv->bss_mode = type; mwifiex_deauthenticate(priv, NULL); priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; @@ -896,90 +804,6 @@ static int mwifiex_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, return 0; } -/* cfg80211 operation handler for stop ap. - * Function stops BSS running at uAP interface. - */ -static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) -{ - struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - - if (mwifiex_del_mgmt_ies(priv)) - wiphy_err(wiphy, "Failed to delete mgmt IEs!\n"); - - if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, - HostCmd_ACT_GEN_SET, 0, NULL)) { - wiphy_err(wiphy, "Failed to stop the BSS\n"); - return -1; - } - - return 0; -} - -/* cfg80211 operation handler for start_ap. - * Function sets beacon period, DTIM period, SSID and security into - * AP config structure. - * AP is configured with these settings and BSS is started. - */ -static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, - struct net_device *dev, - struct cfg80211_ap_settings *params) -{ - struct mwifiex_uap_bss_param *bss_cfg; - struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - - if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) - return -1; - if (mwifiex_set_mgmt_ies(priv, params)) - return -1; - - bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL); - if (!bss_cfg) - return -ENOMEM; - - mwifiex_set_sys_config_invalid_data(bss_cfg); - - if (params->beacon_interval) - bss_cfg->beacon_period = params->beacon_interval; - if (params->dtim_period) - bss_cfg->dtim_period = params->dtim_period; - - if (params->ssid && params->ssid_len) { - memcpy(bss_cfg->ssid.ssid, params->ssid, params->ssid_len); - bss_cfg->ssid.ssid_len = params->ssid_len; - } - - if (mwifiex_set_secure_params(priv, bss_cfg, params)) { - kfree(bss_cfg); - wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); - return -1; - } - - if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, - HostCmd_ACT_GEN_SET, 0, NULL)) { - wiphy_err(wiphy, "Failed to stop the BSS\n"); - kfree(bss_cfg); - return -1; - } - - if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG, - HostCmd_ACT_GEN_SET, - UAP_BSS_PARAMS_I, bss_cfg)) { - wiphy_err(wiphy, "Failed to set the SSID\n"); - kfree(bss_cfg); - return -1; - } - - kfree(bss_cfg); - - if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_BSS_START, - HostCmd_ACT_GEN_SET, 0, NULL)) { - wiphy_err(wiphy, "Failed to start the BSS\n"); - return -1; - } - - return 0; -} - /* * CFG802.11 operation handler for disconnection request. * @@ -1099,7 +923,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, priv->wep_key_curr_index = 0; priv->sec_info.encryption_mode = 0; priv->sec_info.is_authtype_auto = 0; - ret = mwifiex_set_encode(priv, NULL, 0, 0, NULL, 1); + ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); if (mode == NL80211_IFTYPE_ADHOC) { /* "privacy" is set only for ad-hoc mode */ @@ -1147,7 +971,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, " with key len %d\n", sme->key_len); priv->wep_key_curr_index = sme->key_idx; ret = mwifiex_set_encode(priv, sme->key, sme->key_len, - sme->key_idx, NULL, 0); + sme->key_idx, 0); } } done: @@ -1226,11 +1050,6 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, goto done; } - if (priv->bss_mode == NL80211_IFTYPE_AP) { - wiphy_err(wiphy, "skip association request for AP interface\n"); - goto done; - } - wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", (char *) sme->ssid, sme->bssid); @@ -1464,12 +1283,15 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, u32 *flags, struct vif_params *params) { - struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); - struct mwifiex_private *priv; + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_adapter *adapter; struct net_device *dev; void *mdev_priv; - struct wireless_dev *wdev; + if (!priv) + return NULL; + + adapter = priv->adapter; if (!adapter) return NULL; @@ -1477,21 +1299,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: - priv = adapter->priv[MWIFIEX_BSS_TYPE_STA]; if (priv->bss_mode) { - wiphy_err(wiphy, - "cannot create multiple sta/adhoc ifaces\n"); + wiphy_err(wiphy, "cannot create multiple" + " station/adhoc interfaces\n"); return NULL; } - wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); - if (!wdev) - return NULL; - - wdev->wiphy = wiphy; - priv->wdev = wdev; - wdev->iftype = NL80211_IFTYPE_STATION; - if (type == NL80211_IFTYPE_UNSPECIFIED) priv->bss_mode = NL80211_IFTYPE_STATION; else @@ -1499,35 +1312,10 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_type = MWIFIEX_BSS_TYPE_STA; priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; - priv->bss_priority = MWIFIEX_BSS_ROLE_STA; + priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_STA; priv->bss_num = 0; - break; - case NL80211_IFTYPE_AP: - priv = adapter->priv[MWIFIEX_BSS_TYPE_UAP]; - - if (priv->bss_mode) { - wiphy_err(wiphy, "Can't create multiple AP interfaces"); - return NULL; - } - - wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); - if (!wdev) - return NULL; - - priv->wdev = wdev; - wdev->wiphy = wiphy; - wdev->iftype = NL80211_IFTYPE_AP; - - priv->bss_type = MWIFIEX_BSS_TYPE_UAP; - priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; - priv->bss_priority = MWIFIEX_BSS_ROLE_UAP; - priv->bss_role = MWIFIEX_BSS_ROLE_UAP; - priv->bss_started = 0; - priv->bss_num = 0; - priv->bss_mode = type; - break; default: wiphy_err(wiphy, "type not supported\n"); @@ -1541,15 +1329,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, goto error; } - mwifiex_init_priv_params(priv, dev); - priv->netdev = dev; - - mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); - - if (adapter->config_bands & BAND_A) - mwifiex_setup_ht_caps( - &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); - dev_net_set(dev, wiphy_net(wiphy)); dev->ieee80211_ptr = priv->wdev; dev->ieee80211_ptr->iftype = priv->bss_mode; @@ -1564,6 +1343,9 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, mdev_priv = netdev_priv(dev); *((unsigned long *) mdev_priv) = (unsigned long) priv; + priv->netdev = dev; + mwifiex_init_priv_params(priv, dev); + SET_NETDEV_DEV(dev, adapter->dev); /* Register network device */ @@ -1635,6 +1417,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { .get_station = mwifiex_cfg80211_get_station, .dump_station = mwifiex_cfg80211_dump_station, .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params, + .set_channel = mwifiex_cfg80211_set_channel, .join_ibss = mwifiex_cfg80211_join_ibss, .leave_ibss = mwifiex_cfg80211_leave_ibss, .add_key = mwifiex_cfg80211_add_key, @@ -1643,8 +1426,6 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, .set_tx_power = mwifiex_cfg80211_set_tx_power, .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask, - .start_ap = mwifiex_cfg80211_start_ap, - .stop_ap = mwifiex_cfg80211_stop_ap, .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config, }; @@ -1655,67 +1436,82 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { * default parameters and handler function pointers, and finally * registers the device. */ - -int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) +int mwifiex_register_cfg80211(struct mwifiex_private *priv) { int ret; void *wdev_priv; - struct wiphy *wiphy; - struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA]; + struct wireless_dev *wdev; + struct ieee80211_sta_ht_cap *ht_info; u8 *country_code; - /* create a new wiphy for use with cfg80211 */ - wiphy = wiphy_new(&mwifiex_cfg80211_ops, - sizeof(struct mwifiex_adapter *)); - if (!wiphy) { - dev_err(adapter->dev, "%s: creating new wiphy\n", __func__); + wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); + if (!wdev) { + dev_err(priv->adapter->dev, "%s: allocating wireless device\n", + __func__); return -ENOMEM; } - wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH; - wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN; - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_AP); - - wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; - if (adapter->config_bands & BAND_A) - wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; - else - wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; - - wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta; - wiphy->n_iface_combinations = 1; + wdev->wiphy = + wiphy_new(&mwifiex_cfg80211_ops, + sizeof(struct mwifiex_private *)); + if (!wdev->wiphy) { + kfree(wdev); + return -ENOMEM; + } + wdev->iftype = NL80211_IFTYPE_STATION; + wdev->wiphy->max_scan_ssids = 10; + wdev->wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN; + wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + + wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; + ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap; + mwifiex_setup_ht_caps(ht_info, priv); + + if (priv->adapter->config_bands & BAND_A) { + wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; + ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap; + mwifiex_setup_ht_caps(ht_info, priv); + } else { + wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; + } /* Initialize cipher suits */ - wiphy->cipher_suites = mwifiex_cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); + wdev->wiphy->cipher_suites = mwifiex_cipher_suites; + wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); - memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN); - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_CUSTOM_REGULATORY; + memcpy(wdev->wiphy->perm_addr, priv->curr_addr, ETH_ALEN); + wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; /* Reserve space for mwifiex specific private data for BSS */ - wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); + wdev->wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); + + wdev->wiphy->reg_notifier = mwifiex_reg_notifier; - wiphy->reg_notifier = mwifiex_reg_notifier; + /* Set struct mwifiex_private pointer in wiphy_priv */ + wdev_priv = wiphy_priv(wdev->wiphy); - /* Set struct mwifiex_adapter pointer in wiphy_priv */ - wdev_priv = wiphy_priv(wiphy); - *(unsigned long *)wdev_priv = (unsigned long)adapter; + *(unsigned long *) wdev_priv = (unsigned long) priv; - set_wiphy_dev(wiphy, (struct device *)priv->adapter->dev); + set_wiphy_dev(wdev->wiphy, (struct device *) priv->adapter->dev); - ret = wiphy_register(wiphy); + ret = wiphy_register(wdev->wiphy); if (ret < 0) { - dev_err(adapter->dev, - "%s: wiphy_register failed: %d\n", __func__, ret); - wiphy_free(wiphy); + dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", + __func__); + wiphy_free(wdev->wiphy); + kfree(wdev); return ret; + } else { + dev_dbg(priv->adapter->dev, + "info: successfully registered wiphy device\n"); } + country_code = mwifiex_11d_code_2_region(priv->adapter->region_code); - if (country_code && regulatory_hint(wiphy, country_code)) - dev_err(adapter->dev, "regulatory_hint() failed\n"); + if (country_code && regulatory_hint(wdev->wiphy, country_code)) + dev_err(priv->adapter->dev, + "%s: regulatory_hint failed\n", __func__); + + priv->wdev = wdev; - adapter->wiphy = wiphy; return ret; } diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.h b/trunk/drivers/net/wireless/mwifiex/cfg80211.h index c5848934f111..76c76c60438b 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.h +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.h @@ -24,6 +24,6 @@ #include "main.h" -int mwifiex_register_cfg80211(struct mwifiex_adapter *); +int mwifiex_register_cfg80211(struct mwifiex_private *); #endif diff --git a/trunk/drivers/net/wireless/mwifiex/cmdevt.c b/trunk/drivers/net/wireless/mwifiex/cmdevt.c index 51e023ec1de4..1710beffb93a 100644 --- a/trunk/drivers/net/wireless/mwifiex/cmdevt.c +++ b/trunk/drivers/net/wireless/mwifiex/cmdevt.c @@ -440,11 +440,6 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) do_gettimeofday(&tstamp); dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n", tstamp.tv_sec, tstamp.tv_usec, eventcause); - } else { - /* Handle PS_SLEEP/AWAKE events on STA */ - priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); - if (!priv) - priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); } ret = mwifiex_process_sta_event(priv); @@ -545,20 +540,8 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, /* Prepare command */ if (cmd_no) { - switch (cmd_no) { - case HostCmd_CMD_UAP_SYS_CONFIG: - case HostCmd_CMD_UAP_BSS_START: - case HostCmd_CMD_UAP_BSS_STOP: - ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, - cmd_oid, data_buf, - cmd_ptr); - break; - default: - ret = mwifiex_sta_prepare_cmd(priv, cmd_no, cmd_action, - cmd_oid, data_buf, - cmd_ptr); - break; - } + ret = mwifiex_sta_prepare_cmd(priv, cmd_no, cmd_action, + cmd_oid, data_buf, cmd_ptr); } else { ret = mwifiex_cmd_host_cmd(priv, cmd_ptr, data_buf); cmd_node->cmd_flag |= CMD_F_HOSTCMD; diff --git a/trunk/drivers/net/wireless/mwifiex/decl.h b/trunk/drivers/net/wireless/mwifiex/decl.h index f918f66e5e27..d04aba4131dc 100644 --- a/trunk/drivers/net/wireless/mwifiex/decl.h +++ b/trunk/drivers/net/wireless/mwifiex/decl.h @@ -28,7 +28,7 @@ #include -#define MWIFIEX_MAX_BSS_NUM (2) +#define MWIFIEX_MAX_BSS_NUM (1) #define MWIFIEX_MIN_DATA_HEADER_LEN 36 /* sizeof(mwifiex_txpd) * + 4 byte alignment @@ -55,17 +55,11 @@ #define MWIFIEX_RX_DATA_BUF_SIZE (4 * 1024) #define MWIFIEX_RX_CMD_BUF_SIZE (2 * 1024) -#define MAX_BEACON_PERIOD (4000) -#define MIN_BEACON_PERIOD (50) -#define MAX_DTIM_PERIOD (100) -#define MIN_DTIM_PERIOD (1) - #define MWIFIEX_RTS_MIN_VALUE (0) #define MWIFIEX_RTS_MAX_VALUE (2347) #define MWIFIEX_FRAG_MIN_VALUE (256) #define MWIFIEX_FRAG_MAX_VALUE (2346) -#define MWIFIEX_RETRY_LIMIT 14 #define MWIFIEX_SDIO_BLOCK_SIZE 256 #define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) @@ -98,11 +92,6 @@ struct mwifiex_fw_image { u32 fw_len; }; -struct mwifiex_802_11_ssid { - u32 ssid_len; - u8 ssid[IEEE80211_MAX_SSID_LEN]; -}; - struct mwifiex_wait_queue { wait_queue_head_t wait; int status; diff --git a/trunk/drivers/net/wireless/mwifiex/fw.h b/trunk/drivers/net/wireless/mwifiex/fw.h index 9f674bbebe65..5f6adeb9b950 100644 --- a/trunk/drivers/net/wireless/mwifiex/fw.h +++ b/trunk/drivers/net/wireless/mwifiex/fw.h @@ -93,20 +93,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define CAL_SNR(RSSI, NF) ((s16)((s16)(RSSI)-(s16)(NF))) -#define UAP_BSS_PARAMS_I 0 -#define UAP_CUSTOM_IE_I 1 -#define MWIFIEX_AUTO_IDX_MASK 0xffff -#define MWIFIEX_DELETE_MASK 0x0000 -#define MGMT_MASK_ASSOC_REQ 0x01 -#define MGMT_MASK_REASSOC_REQ 0x04 -#define MGMT_MASK_ASSOC_RESP 0x02 -#define MGMT_MASK_REASSOC_RESP 0x08 -#define MGMT_MASK_PROBE_REQ 0x10 -#define MGMT_MASK_PROBE_RESP 0x20 -#define MGMT_MASK_BEACON 0x100 - -#define TLV_TYPE_UAP_SSID 0x0000 - #define PROPRIETARY_TLV_BASE_ID 0x0100 #define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0) #define TLV_TYPE_CHANLIST (PROPRIETARY_TLV_BASE_ID + 1) @@ -118,26 +104,14 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19) #define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22) #define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31) -#define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32) #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) -#define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) -#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) -#define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51) -#define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60) -#define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64) -#define TLV_TYPE_UAP_AKMP (PROPRIETARY_TLV_BASE_ID + 65) -#define TLV_TYPE_UAP_FRAG_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 70) #define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82) #define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83) #define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84) -#define TLV_TYPE_UAP_RETRY_LIMIT (PROPRIETARY_TLV_BASE_ID + 93) #define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94) -#define TLV_TYPE_UAP_MGMT_FRAME (PROPRIETARY_TLV_BASE_ID + 104) #define TLV_TYPE_MGMT_IE (PROPRIETARY_TLV_BASE_ID + 105) #define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113) #define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114) -#define TLV_TYPE_PWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 145) -#define TLV_TYPE_GWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 146) #define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 @@ -235,9 +209,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_RSSI_INFO 0x00a4 #define HostCmd_CMD_FUNC_INIT 0x00a9 #define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa -#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0 -#define HostCmd_CMD_UAP_BSS_START 0x00b1 -#define HostCmd_CMD_UAP_BSS_STOP 0x00b2 #define HostCmd_CMD_11N_CFG 0x00cd #define HostCmd_CMD_11N_ADDBA_REQ 0x00ce #define HostCmd_CMD_11N_ADDBA_RSP 0x00cf @@ -252,19 +223,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_SET_BSS_MODE 0x00f7 #define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa -#define PROTOCOL_NO_SECURITY 0x01 -#define PROTOCOL_STATIC_WEP 0x02 -#define PROTOCOL_WPA 0x08 -#define PROTOCOL_WPA2 0x20 -#define PROTOCOL_WPA2_MIXED 0x28 -#define PROTOCOL_EAP 0x40 -#define KEY_MGMT_NONE 0x04 -#define KEY_MGMT_PSK 0x02 -#define KEY_MGMT_EAP 0x01 -#define CIPHER_TKIP 0x04 -#define CIPHER_AES_CCMP 0x08 -#define VALID_CIPHER_BITMAP 0x0c - enum ENH_PS_MODES { EN_PS = 1, DIS_PS = 2, @@ -355,20 +313,15 @@ enum ENH_PS_MODES { #define EVENT_DATA_SNR_HIGH 0x00000027 #define EVENT_LINK_QUALITY 0x00000028 #define EVENT_PORT_RELEASE 0x0000002b -#define EVENT_UAP_STA_DEAUTH 0x0000002c -#define EVENT_UAP_STA_ASSOC 0x0000002d -#define EVENT_UAP_BSS_START 0x0000002e #define EVENT_PRE_BEACON_LOST 0x00000031 #define EVENT_ADDBA 0x00000033 #define EVENT_DELBA 0x00000034 #define EVENT_BA_STREAM_TIEMOUT 0x00000037 #define EVENT_AMSDU_AGGR_CTRL 0x00000042 -#define EVENT_UAP_BSS_IDLE 0x00000043 -#define EVENT_UAP_BSS_ACTIVE 0x00000044 #define EVENT_WEP_ICV_ERR 0x00000046 #define EVENT_HS_ACT_REQ 0x00000047 #define EVENT_BW_CHANGE 0x00000048 -#define EVENT_UAP_MIC_COUNTERMEASURES 0x0000004c + #define EVENT_HOSTWAKE_STAIE 0x0000004d #define EVENT_ID_MASK 0xffff @@ -1150,101 +1103,6 @@ struct host_cmd_ds_802_11_eeprom_access { u8 value; } __packed; -struct host_cmd_tlv { - __le16 type; - __le16 len; -} __packed; - -struct mwifiex_assoc_event { - u8 sta_addr[ETH_ALEN]; - __le16 type; - __le16 len; - __le16 frame_control; - __le16 cap_info; - __le16 listen_interval; - u8 data[0]; -} __packed; - -struct host_cmd_ds_sys_config { - __le16 action; - u8 tlv[0]; -}; - -struct host_cmd_tlv_akmp { - struct host_cmd_tlv tlv; - __le16 key_mgmt; - __le16 key_mgmt_operation; -} __packed; - -struct host_cmd_tlv_pwk_cipher { - struct host_cmd_tlv tlv; - __le16 proto; - u8 cipher; - u8 reserved; -} __packed; - -struct host_cmd_tlv_gwk_cipher { - struct host_cmd_tlv tlv; - u8 cipher; - u8 reserved; -} __packed; - -struct host_cmd_tlv_passphrase { - struct host_cmd_tlv tlv; - u8 passphrase[0]; -} __packed; - -struct host_cmd_tlv_auth_type { - struct host_cmd_tlv tlv; - u8 auth_type; -} __packed; - -struct host_cmd_tlv_encrypt_protocol { - struct host_cmd_tlv tlv; - __le16 proto; -} __packed; - -struct host_cmd_tlv_ssid { - struct host_cmd_tlv tlv; - u8 ssid[0]; -} __packed; - -struct host_cmd_tlv_beacon_period { - struct host_cmd_tlv tlv; - __le16 period; -} __packed; - -struct host_cmd_tlv_dtim_period { - struct host_cmd_tlv tlv; - u8 period; -} __packed; - -struct host_cmd_tlv_frag_threshold { - struct host_cmd_tlv tlv; - __le16 frag_thr; -} __packed; - -struct host_cmd_tlv_rts_threshold { - struct host_cmd_tlv tlv; - __le16 rts_thr; -} __packed; - -struct host_cmd_tlv_retry_limit { - struct host_cmd_tlv tlv; - u8 limit; -} __packed; - -struct host_cmd_tlv_mac_addr { - struct host_cmd_tlv tlv; - u8 mac_addr[ETH_ALEN]; -} __packed; - -struct host_cmd_tlv_channel_band { - struct host_cmd_tlv tlv; - u8 band_config; - u8 channel; -} __packed; - struct host_cmd_ds_802_11_rf_channel { __le16 action; __le16 current_channel; @@ -1309,20 +1167,6 @@ struct host_cmd_ds_802_11_subsc_evt { __le16 events; } __packed; -struct mwifiex_ie { - __le16 ie_index; - __le16 mgmt_subtype_mask; - __le16 ie_length; - u8 ie_buffer[IEEE_MAX_IE_SIZE]; -} __packed; - -#define MAX_MGMT_IE_INDEX 16 -struct mwifiex_ie_list { - __le16 type; - __le16 len; - struct mwifiex_ie ie_list[MAX_MGMT_IE_INDEX]; -} __packed; - struct host_cmd_ds_command { __le16 command; __le16 size; @@ -1373,7 +1217,6 @@ struct host_cmd_ds_command { struct host_cmd_ds_pcie_details pcie_host_spec; struct host_cmd_ds_802_11_eeprom_access eeprom; struct host_cmd_ds_802_11_subsc_evt subsc_evt; - struct host_cmd_ds_sys_config uap_sys_config; } params; } __packed; diff --git a/trunk/drivers/net/wireless/mwifiex/ie.c b/trunk/drivers/net/wireless/mwifiex/ie.c deleted file mode 100644 index ceb82cd749cc..000000000000 --- a/trunk/drivers/net/wireless/mwifiex/ie.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Marvell Wireless LAN device driver: management IE handling- setting and - * deleting IE. - * - * Copyright (C) 2012, Marvell International Ltd. - * - * This software file (the "File") is distributed by Marvell International - * Ltd. under the terms of the GNU General Public License Version 2, June 1991 - * (the "License"). You may use, redistribute and/or modify this File in - * accordance with the terms and conditions of the License, a copy of which - * is available by writing to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the - * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. - * - * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE - * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE - * ARE EXPRESSLY DISCLAIMED. The License provides additional details about - * this warranty disclaimer. - */ - -#include "main.h" - -/* This function checks if current IE index is used by any on other interface. - * Return: -1: yes, current IE index is used by someone else. - * 0: no, current IE index is NOT used by other interface. - */ -static int -mwifiex_ie_index_used_by_other_intf(struct mwifiex_private *priv, u16 idx) -{ - int i; - struct mwifiex_adapter *adapter = priv->adapter; - struct mwifiex_ie *ie; - - for (i = 0; i < adapter->priv_num; i++) { - if (adapter->priv[i] != priv) { - ie = &adapter->priv[i]->mgmt_ie[idx]; - if (ie->mgmt_subtype_mask && ie->ie_length) - return -1; - } - } - - return 0; -} - -/* Get unused IE index. This index will be used for setting new IE */ -static int -mwifiex_ie_get_autoidx(struct mwifiex_private *priv, u16 subtype_mask, - struct mwifiex_ie *ie, u16 *index) -{ - u16 mask, len, i; - - for (i = 0; i < priv->adapter->max_mgmt_ie_index; i++) { - mask = le16_to_cpu(priv->mgmt_ie[i].mgmt_subtype_mask); - len = le16_to_cpu(priv->mgmt_ie[i].ie_length) + - le16_to_cpu(ie->ie_length); - - if (mask == MWIFIEX_AUTO_IDX_MASK) - continue; - - if (mask == subtype_mask) { - if (len > IEEE_MAX_IE_SIZE) - continue; - - *index = i; - return 0; - } - - if (!priv->mgmt_ie[i].ie_length) { - if (mwifiex_ie_index_used_by_other_intf(priv, i)) - continue; - - *index = i; - return 0; - } - } - - return -1; -} - -/* This function prepares IE data buffer for command to be sent to FW */ -static int -mwifiex_update_autoindex_ies(struct mwifiex_private *priv, - struct mwifiex_ie_list *ie_list) -{ - u16 travel_len, index, mask; - s16 input_len; - struct mwifiex_ie *ie; - u8 *tmp; - - input_len = le16_to_cpu(ie_list->len); - travel_len = sizeof(struct host_cmd_tlv); - - ie_list->len = 0; - - while (input_len > 0) { - ie = (struct mwifiex_ie *)(((u8 *)ie_list) + travel_len); - input_len -= le16_to_cpu(ie->ie_length) + MWIFIEX_IE_HDR_SIZE; - travel_len += le16_to_cpu(ie->ie_length) + MWIFIEX_IE_HDR_SIZE; - - index = le16_to_cpu(ie->ie_index); - mask = le16_to_cpu(ie->mgmt_subtype_mask); - - if (index == MWIFIEX_AUTO_IDX_MASK) { - /* automatic addition */ - if (mwifiex_ie_get_autoidx(priv, mask, ie, &index)) - return -1; - if (index == MWIFIEX_AUTO_IDX_MASK) - return -1; - - tmp = (u8 *)&priv->mgmt_ie[index].ie_buffer; - tmp += le16_to_cpu(priv->mgmt_ie[index].ie_length); - memcpy(tmp, &ie->ie_buffer, le16_to_cpu(ie->ie_length)); - le16_add_cpu(&priv->mgmt_ie[index].ie_length, - le16_to_cpu(ie->ie_length)); - priv->mgmt_ie[index].ie_index = cpu_to_le16(index); - priv->mgmt_ie[index].mgmt_subtype_mask = - cpu_to_le16(mask); - - ie->ie_index = cpu_to_le16(index); - ie->ie_length = priv->mgmt_ie[index].ie_length; - memcpy(&ie->ie_buffer, &priv->mgmt_ie[index].ie_buffer, - le16_to_cpu(priv->mgmt_ie[index].ie_length)); - } else { - if (mask != MWIFIEX_DELETE_MASK) - return -1; - /* - * Check if this index is being used on any - * other interface. - */ - if (mwifiex_ie_index_used_by_other_intf(priv, index)) - return -1; - - ie->ie_length = 0; - memcpy(&priv->mgmt_ie[index], ie, - sizeof(struct mwifiex_ie)); - } - - le16_add_cpu(&ie_list->len, - le16_to_cpu(priv->mgmt_ie[index].ie_length) + - MWIFIEX_IE_HDR_SIZE); - } - - if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) - return mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG, - HostCmd_ACT_GEN_SET, - UAP_CUSTOM_IE_I, ie_list); - - return 0; -} - -/* Copy individual custom IEs for beacon, probe response and assoc response - * and prepare single structure for IE setting. - * This function also updates allocated IE indices from driver. - */ -static int -mwifiex_update_uap_custom_ie(struct mwifiex_private *priv, - struct mwifiex_ie *beacon_ie, u16 *beacon_idx, - struct mwifiex_ie *pr_ie, u16 *probe_idx, - struct mwifiex_ie *ar_ie, u16 *assoc_idx) -{ - struct mwifiex_ie_list *ap_custom_ie; - u8 *pos; - u16 len; - int ret; - - ap_custom_ie = kzalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); - if (!ap_custom_ie) - return -ENOMEM; - - ap_custom_ie->type = cpu_to_le16(TLV_TYPE_MGMT_IE); - pos = (u8 *)ap_custom_ie->ie_list; - - if (beacon_ie) { - len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE + - le16_to_cpu(beacon_ie->ie_length); - memcpy(pos, beacon_ie, len); - pos += len; - le16_add_cpu(&ap_custom_ie->len, len); - } - if (pr_ie) { - len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE + - le16_to_cpu(pr_ie->ie_length); - memcpy(pos, pr_ie, len); - pos += len; - le16_add_cpu(&ap_custom_ie->len, len); - } - if (ar_ie) { - len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE + - le16_to_cpu(ar_ie->ie_length); - memcpy(pos, ar_ie, len); - pos += len; - le16_add_cpu(&ap_custom_ie->len, len); - } - - ret = mwifiex_update_autoindex_ies(priv, ap_custom_ie); - - pos = (u8 *)(&ap_custom_ie->ie_list[0].ie_index); - if (beacon_ie && *beacon_idx == MWIFIEX_AUTO_IDX_MASK) { - /* save beacon ie index after auto-indexing */ - *beacon_idx = le16_to_cpu(ap_custom_ie->ie_list[0].ie_index); - len = sizeof(*beacon_ie) - IEEE_MAX_IE_SIZE + - le16_to_cpu(beacon_ie->ie_length); - pos += len; - } - if (pr_ie && le16_to_cpu(pr_ie->ie_index) == MWIFIEX_AUTO_IDX_MASK) { - /* save probe resp ie index after auto-indexing */ - *probe_idx = *((u16 *)pos); - len = sizeof(*pr_ie) - IEEE_MAX_IE_SIZE + - le16_to_cpu(pr_ie->ie_length); - pos += len; - } - if (ar_ie && le16_to_cpu(ar_ie->ie_index) == MWIFIEX_AUTO_IDX_MASK) - /* save assoc resp ie index after auto-indexing */ - *assoc_idx = *((u16 *)pos); - - return ret; -} - -/* This function parses different IEs- Tail IEs, beacon IEs, probe response IEs, - * association response IEs from cfg80211_ap_settings function and sets these IE - * to FW. - */ -int mwifiex_set_mgmt_ies(struct mwifiex_private *priv, - struct cfg80211_ap_settings *params) -{ - struct mwifiex_ie *beacon_ie = NULL, *pr_ie = NULL; - struct mwifiex_ie *ar_ie = NULL, *rsn_ie = NULL; - struct ieee_types_header *ie = NULL; - u16 beacon_idx = MWIFIEX_AUTO_IDX_MASK, pr_idx = MWIFIEX_AUTO_IDX_MASK; - u16 ar_idx = MWIFIEX_AUTO_IDX_MASK, rsn_idx = MWIFIEX_AUTO_IDX_MASK; - u16 mask; - int ret = 0; - - if (params->beacon.tail && params->beacon.tail_len) { - ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, params->beacon.tail, - params->beacon.tail_len); - if (ie) { - rsn_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); - if (!rsn_ie) - return -ENOMEM; - - rsn_ie->ie_index = cpu_to_le16(rsn_idx); - mask = MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP | - MGMT_MASK_ASSOC_RESP; - rsn_ie->mgmt_subtype_mask = cpu_to_le16(mask); - rsn_ie->ie_length = cpu_to_le16(ie->len + 2); - memcpy(rsn_ie->ie_buffer, ie, ie->len + 2); - - if (mwifiex_update_uap_custom_ie(priv, rsn_ie, &rsn_idx, - NULL, NULL, - NULL, NULL)) { - ret = -1; - goto done; - } - - priv->rsn_idx = rsn_idx; - } - } - - if (params->beacon.beacon_ies && params->beacon.beacon_ies_len) { - beacon_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); - if (!beacon_ie) { - ret = -ENOMEM; - goto done; - } - - beacon_ie->ie_index = cpu_to_le16(beacon_idx); - beacon_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON); - beacon_ie->ie_length = - cpu_to_le16(params->beacon.beacon_ies_len); - memcpy(beacon_ie->ie_buffer, params->beacon.beacon_ies, - params->beacon.beacon_ies_len); - } - - if (params->beacon.proberesp_ies && params->beacon.proberesp_ies_len) { - pr_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); - if (!pr_ie) { - ret = -ENOMEM; - goto done; - } - - pr_ie->ie_index = cpu_to_le16(pr_idx); - pr_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_PROBE_RESP); - pr_ie->ie_length = - cpu_to_le16(params->beacon.proberesp_ies_len); - memcpy(pr_ie->ie_buffer, params->beacon.proberesp_ies, - params->beacon.proberesp_ies_len); - } - - if (params->beacon.assocresp_ies && params->beacon.assocresp_ies_len) { - ar_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); - if (!ar_ie) { - ret = -ENOMEM; - goto done; - } - - ar_ie->ie_index = cpu_to_le16(ar_idx); - mask = MGMT_MASK_ASSOC_RESP | MGMT_MASK_REASSOC_RESP; - ar_ie->mgmt_subtype_mask = cpu_to_le16(mask); - ar_ie->ie_length = - cpu_to_le16(params->beacon.assocresp_ies_len); - memcpy(ar_ie->ie_buffer, params->beacon.assocresp_ies, - params->beacon.assocresp_ies_len); - } - - if (beacon_ie || pr_ie || ar_ie) { - ret = mwifiex_update_uap_custom_ie(priv, beacon_ie, - &beacon_idx, pr_ie, - &pr_idx, ar_ie, &ar_idx); - if (ret) - goto done; - } - - priv->beacon_idx = beacon_idx; - priv->proberesp_idx = pr_idx; - priv->assocresp_idx = ar_idx; - -done: - kfree(beacon_ie); - kfree(pr_ie); - kfree(ar_ie); - kfree(rsn_ie); - - return ret; -} - -/* This function removes management IE set */ -int mwifiex_del_mgmt_ies(struct mwifiex_private *priv) -{ - struct mwifiex_ie *beacon_ie = NULL, *pr_ie = NULL; - struct mwifiex_ie *ar_ie = NULL, *rsn_ie = NULL; - int ret = 0; - - if (priv->rsn_idx != MWIFIEX_AUTO_IDX_MASK) { - rsn_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); - if (!rsn_ie) - return -ENOMEM; - - rsn_ie->ie_index = cpu_to_le16(priv->rsn_idx); - rsn_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK); - rsn_ie->ie_length = 0; - if (mwifiex_update_uap_custom_ie(priv, rsn_ie, &priv->rsn_idx, - NULL, &priv->proberesp_idx, - NULL, &priv->assocresp_idx)) { - ret = -1; - goto done; - } - - priv->rsn_idx = MWIFIEX_AUTO_IDX_MASK; - } - - if (priv->beacon_idx != MWIFIEX_AUTO_IDX_MASK) { - beacon_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); - if (!beacon_ie) { - ret = -ENOMEM; - goto done; - } - beacon_ie->ie_index = cpu_to_le16(priv->beacon_idx); - beacon_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK); - beacon_ie->ie_length = 0; - } - if (priv->proberesp_idx != MWIFIEX_AUTO_IDX_MASK) { - pr_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); - if (!pr_ie) { - ret = -ENOMEM; - goto done; - } - pr_ie->ie_index = cpu_to_le16(priv->proberesp_idx); - pr_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK); - pr_ie->ie_length = 0; - } - if (priv->assocresp_idx != MWIFIEX_AUTO_IDX_MASK) { - ar_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); - if (!ar_ie) { - ret = -ENOMEM; - goto done; - } - ar_ie->ie_index = cpu_to_le16(priv->assocresp_idx); - ar_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK); - ar_ie->ie_length = 0; - } - - if (beacon_ie || pr_ie || ar_ie) - ret = mwifiex_update_uap_custom_ie(priv, - beacon_ie, &priv->beacon_idx, - pr_ie, &priv->proberesp_idx, - ar_ie, &priv->assocresp_idx); - -done: - kfree(beacon_ie); - kfree(pr_ie); - kfree(ar_ie); - kfree(rsn_ie); - - return ret; -} diff --git a/trunk/drivers/net/wireless/mwifiex/init.c b/trunk/drivers/net/wireless/mwifiex/init.c index c1cb004db913..d440c3eb640b 100644 --- a/trunk/drivers/net/wireless/mwifiex/init.c +++ b/trunk/drivers/net/wireless/mwifiex/init.c @@ -279,7 +279,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); adapter->arp_filter_size = 0; adapter->channel_type = NL80211_CHAN_HT20; - adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; } /* diff --git a/trunk/drivers/net/wireless/mwifiex/ioctl.h b/trunk/drivers/net/wireless/mwifiex/ioctl.h index e6be6ee75951..f0f95524e96b 100644 --- a/trunk/drivers/net/wireless/mwifiex/ioctl.h +++ b/trunk/drivers/net/wireless/mwifiex/ioctl.h @@ -62,36 +62,6 @@ enum { BAND_AN = 16, }; -#define MWIFIEX_WPA_PASSHPHRASE_LEN 64 -struct wpa_param { - u8 pairwise_cipher_wpa; - u8 pairwise_cipher_wpa2; - u8 group_cipher; - u32 length; - u8 passphrase[MWIFIEX_WPA_PASSHPHRASE_LEN]; -}; - -#define KEY_MGMT_ON_HOST 0x03 -#define MWIFIEX_AUTH_MODE_AUTO 0xFF -#define BAND_CONFIG_MANUAL 0x00 -struct mwifiex_uap_bss_param { - u8 channel; - u8 band_cfg; - u16 rts_threshold; - u16 frag_threshold; - u8 retry_limit; - struct mwifiex_802_11_ssid ssid; - u8 bcast_ssid_ctl; - u8 radio_ctl; - u8 dtim_period; - u16 beacon_period; - u16 auth_mode; - u16 protocol; - u16 key_mgmt; - u16 key_mgmt_operation; - struct wpa_param wpa_cfg; -}; - enum { ADHOC_IDLE, ADHOC_STARTED, @@ -299,8 +269,6 @@ struct mwifiex_ds_read_eeprom { #define IEEE_MAX_IE_SIZE 256 -#define MWIFIEX_IE_HDR_SIZE (sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE) - struct mwifiex_ds_misc_gen_ie { u32 type; u32 len; diff --git a/trunk/drivers/net/wireless/mwifiex/join.c b/trunk/drivers/net/wireless/mwifiex/join.c index d6b4fb04011f..8a390982463e 100644 --- a/trunk/drivers/net/wireless/mwifiex/join.c +++ b/trunk/drivers/net/wireless/mwifiex/join.c @@ -1374,28 +1374,22 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac) * * In case of infra made, it sends deauthentication request, and * in case of ad-hoc mode, a stop network request is sent to the firmware. - * In AP mode, a command to stop bss is sent to firmware. */ int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac) { - if (!priv->media_connected) - return 0; + int ret = 0; - switch (priv->bss_mode) { - case NL80211_IFTYPE_STATION: - return mwifiex_deauthenticate_infra(priv, mac); - case NL80211_IFTYPE_ADHOC: - return mwifiex_send_cmd_sync(priv, - HostCmd_CMD_802_11_AD_HOC_STOP, - HostCmd_ACT_GEN_SET, 0, NULL); - case NL80211_IFTYPE_AP: - return mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, - HostCmd_ACT_GEN_SET, 0, NULL); - default: - break; + if (priv->media_connected) { + if (priv->bss_mode == NL80211_IFTYPE_STATION) { + ret = mwifiex_deauthenticate_infra(priv, mac); + } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { + ret = mwifiex_send_cmd_sync(priv, + HostCmd_CMD_802_11_AD_HOC_STOP, + HostCmd_ACT_GEN_SET, 0, NULL); + } } - return 0; + return ret; } EXPORT_SYMBOL_GPL(mwifiex_deauthenticate); diff --git a/trunk/drivers/net/wireless/mwifiex/main.c b/trunk/drivers/net/wireless/mwifiex/main.c index 3192855c31c0..be0f0e583f75 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.c +++ b/trunk/drivers/net/wireless/mwifiex/main.c @@ -64,17 +64,17 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, adapter->priv_num = 0; - for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) { - /* Allocate memory for private structure */ - adapter->priv[i] = - kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL); - if (!adapter->priv[i]) - goto error; - - adapter->priv[i]->adapter = adapter; - adapter->priv[i]->bss_priority = i; - adapter->priv_num++; + /* Allocate memory for private structure */ + adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL); + if (!adapter->priv[0]) { + dev_err(adapter->dev, + "%s: failed to alloc priv[0]\n", __func__); + goto error; } + + adapter->priv_num++; + + adapter->priv[0]->adapter = adapter; mwifiex_init_lock_list(adapter); init_timer(&adapter->cmd_timer); @@ -349,26 +349,19 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) goto done; - priv = adapter->priv[MWIFIEX_BSS_ROLE_STA]; - if (mwifiex_register_cfg80211(adapter)) { + priv = adapter->priv[0]; + if (mwifiex_register_cfg80211(priv) != 0) { dev_err(adapter->dev, "cannot register with cfg80211\n"); goto err_init_fw; } rtnl_lock(); /* Create station interface by default */ - if (!mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", + if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d", NL80211_IFTYPE_STATION, NULL, NULL)) { dev_err(adapter->dev, "cannot create default STA interface\n"); goto err_add_intf; } - - /* Create AP interface by default */ - if (!mwifiex_add_virtual_intf(adapter->wiphy, "uap%d", - NL80211_IFTYPE_AP, NULL, NULL)) { - dev_err(adapter->dev, "cannot create default AP interface\n"); - goto err_add_intf; - } rtnl_unlock(); mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1); @@ -376,7 +369,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) goto done; err_add_intf: - mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev); + mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev); rtnl_unlock(); err_init_fw: pr_debug("info: %s: unregister device\n", __func__); @@ -640,12 +633,6 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv, priv->current_key_index = 0; priv->media_connected = false; memset(&priv->nick_name, 0, sizeof(priv->nick_name)); - memset(priv->mgmt_ie, 0, - sizeof(struct mwifiex_ie) * MAX_MGMT_IE_INDEX); - priv->beacon_idx = MWIFIEX_AUTO_IDX_MASK; - priv->proberesp_idx = MWIFIEX_AUTO_IDX_MASK; - priv->assocresp_idx = MWIFIEX_AUTO_IDX_MASK; - priv->rsn_idx = MWIFIEX_AUTO_IDX_MASK; priv->num_tx_timeout = 0; memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); } @@ -843,21 +830,19 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) rtnl_lock(); if (priv->wdev && priv->netdev) - mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev); + mwifiex_del_virtual_intf(priv->wdev->wiphy, + priv->netdev); rtnl_unlock(); } priv = adapter->priv[0]; - if (!priv || !priv->wdev) + if (!priv) goto exit_remove; - wiphy_unregister(priv->wdev->wiphy); - wiphy_free(priv->wdev->wiphy); - - for (i = 0; i < adapter->priv_num; i++) { - priv = adapter->priv[i]; - if (priv) - kfree(priv->wdev); + if (priv->wdev) { + wiphy_unregister(priv->wdev->wiphy); + wiphy_free(priv->wdev->wiphy); + kfree(priv->wdev); } mwifiex_terminate_workqueue(adapter); diff --git a/trunk/drivers/net/wireless/mwifiex/main.h b/trunk/drivers/net/wireless/mwifiex/main.h index bd3b0bf94b9e..324ad390cacd 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.h +++ b/trunk/drivers/net/wireless/mwifiex/main.h @@ -116,7 +116,6 @@ enum { #define MAX_FREQUENCY_BAND_BG 2484 #define MWIFIEX_EVENT_HEADER_LEN 4 -#define MWIFIEX_UAP_EVENT_EXTRA_HEADER 2 #define MWIFIEX_TYPE_LEN 4 #define MWIFIEX_USB_TYPE_CMD 0xF00DFACE @@ -371,7 +370,6 @@ struct mwifiex_private { u8 bss_role; u8 bss_priority; u8 bss_num; - u8 bss_started; u8 frame_type; u8 curr_addr[ETH_ALEN]; u8 media_connected; @@ -472,16 +470,12 @@ struct mwifiex_private { struct cfg80211_scan_request *scan_request; struct mwifiex_user_scan_cfg *user_scan_cfg; u8 cfg_bssid[6]; + u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; struct wps wps; u8 scan_block; s32 cqm_rssi_thold; u32 cqm_rssi_hyst; u8 subsc_evt_rssi_state; - struct mwifiex_ie mgmt_ie[MAX_MGMT_IE_INDEX]; - u16 beacon_idx; - u16 proberesp_idx; - u16 assocresp_idx; - u16 rsn_idx; }; enum mwifiex_ba_status { @@ -577,7 +571,6 @@ struct mwifiex_adapter { char fw_name[32]; int winner; struct device *dev; - struct wiphy *wiphy; bool surprise_removed; u32 fw_release_number; u16 init_wait_q_woken; @@ -684,8 +677,6 @@ struct mwifiex_adapter { struct cmd_ctrl_node *cmd_queued; spinlock_t queue_lock; /* lock for tx queues */ struct completion fw_load; - u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; - u16 max_mgmt_ie_index; }; int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); @@ -769,9 +760,6 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, u16 cmd_action, u32 cmd_oid, void *data_buf, void *cmd_buf); -int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, - u16 cmd_action, u32 cmd_oid, - void *data_buf, void *cmd_buf); int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, struct host_cmd_ds_command *resp); int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, @@ -832,9 +820,6 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, int is_command_pending(struct mwifiex_adapter *adapter); void mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev); -int mwifiex_set_secure_params(struct mwifiex_private *priv, - struct mwifiex_uap_bss_param *bss_config, - struct cfg80211_ap_settings *params); /* * This function checks if the queuing is RA based or not. @@ -948,8 +933,7 @@ int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel); int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, - int key_len, u8 key_index, const u8 *mac_addr, - int disable); + int key_len, u8 key_index, int disable); int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len); @@ -985,7 +969,6 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, int mwifiex_main_process(struct mwifiex_adapter *); -int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel); int mwifiex_bss_set_channel(struct mwifiex_private *, struct mwifiex_chan_freq_power *cfp); int mwifiex_get_bss_info(struct mwifiex_private *, @@ -1003,11 +986,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, u32 *flags, struct vif_params *params); int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev); -void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config); - -int mwifiex_set_mgmt_ies(struct mwifiex_private *priv, - struct cfg80211_ap_settings *params); -int mwifiex_del_mgmt_ies(struct mwifiex_private *priv); u8 *mwifiex_11d_code_2_region(u8 code); #ifdef CONFIG_DEBUG_FS diff --git a/trunk/drivers/net/wireless/mwifiex/sta_cmd.c b/trunk/drivers/net/wireless/mwifiex/sta_cmd.c index 40e025da6bc2..87ed2a1f6cd9 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_cmd.c @@ -498,8 +498,7 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, { struct host_cmd_ds_802_11_key_material *key_material = &cmd->params.key_material; - struct host_cmd_tlv_mac_addr *tlv_mac; - u16 key_param_len = 0, cmd_size; + u16 key_param_len = 0; int ret = 0; const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -615,26 +614,11 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, cpu_to_le16((u16) enc_key->key_len + KEYPARAMSET_FIXED_LEN); - key_param_len = (u16)(enc_key->key_len + KEYPARAMSET_FIXED_LEN) + key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN) + sizeof(struct mwifiex_ie_types_header); cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN + key_param_len); - - if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) { - tlv_mac = (void *)((u8 *)&key_material->key_param_set + - key_param_len); - tlv_mac->tlv.type = cpu_to_le16(TLV_TYPE_STA_MAC_ADDR); - tlv_mac->tlv.len = cpu_to_le16(ETH_ALEN); - memcpy(tlv_mac->mac_addr, enc_key->mac_addr, ETH_ALEN); - cmd_size = key_param_len + S_DS_GEN + - sizeof(key_material->action) + - sizeof(struct host_cmd_tlv_mac_addr); - } else { - cmd_size = key_param_len + S_DS_GEN + - sizeof(key_material->action); - } - cmd->size = cpu_to_le16(cmd_size); } return ret; @@ -1264,15 +1248,13 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) if (ret) return -1; - if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { - /* Enable IEEE PS by default */ - priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; - ret = mwifiex_send_cmd_async( - priv, HostCmd_CMD_802_11_PS_MODE_ENH, - EN_AUTO_PS, BITMAP_STA_PS, NULL); - if (ret) - return -1; - } + /* Enable IEEE PS by default */ + priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_PS_MODE_ENH, + EN_AUTO_PS, BITMAP_STA_PS, NULL); + if (ret) + return -1; } /* get tx rate */ @@ -1288,14 +1270,12 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) if (ret) return -1; - if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) { - /* set ibss coalescing_status */ - ret = mwifiex_send_cmd_async( - priv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, - HostCmd_ACT_GEN_SET, 0, &enable); - if (ret) - return -1; - } + /* set ibss coalescing_status */ + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, + HostCmd_ACT_GEN_SET, 0, &enable); + if (ret) + return -1; memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); amsdu_aggr_ctrl.enable = true; @@ -1313,8 +1293,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) if (ret) return -1; - if (first_sta && priv->adapter->iface_type != MWIFIEX_USB && - priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { + if (first_sta && (priv->adapter->iface_type != MWIFIEX_USB)) { /* Enable auto deep sleep */ auto_ds.auto_ds = DEEP_SLEEP_ON; auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; @@ -1326,16 +1305,12 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) return -1; } - if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { - /* Send cmd to FW to enable/disable 11D function */ - state_11d = ENABLE_11D; - ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB, - HostCmd_ACT_GEN_SET, DOT11D_I, - &state_11d); - if (ret) - dev_err(priv->adapter->dev, - "11D: failed to enable 11D\n"); - } + /* Send cmd to FW to enable/disable 11D function */ + state_11d = ENABLE_11D; + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_SET, DOT11D_I, &state_11d); + if (ret) + dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); /* Send cmd to FW to configure 11n specific configuration * (Short GI, Channel BW, Green field support etc.) for transmit diff --git a/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c b/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c index a79ed9bd9695..3aa54243dea9 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -944,14 +944,6 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: ret = mwifiex_ret_subsc_evt(priv, resp, data_buf); break; - case HostCmd_CMD_UAP_SYS_CONFIG: - break; - case HostCmd_CMD_UAP_BSS_START: - priv->bss_started = 1; - break; - case HostCmd_CMD_UAP_BSS_STOP: - priv->bss_started = 0; - break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", resp->command); diff --git a/trunk/drivers/net/wireless/mwifiex/sta_event.c b/trunk/drivers/net/wireless/mwifiex/sta_event.c index 4ace5a3dcd23..f6bbb9307f86 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_event.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_event.c @@ -184,10 +184,8 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) int mwifiex_process_sta_event(struct mwifiex_private *priv) { struct mwifiex_adapter *adapter = priv->adapter; - int len, ret = 0; + int ret = 0; u32 eventcause = adapter->event_cause; - struct station_info sinfo; - struct mwifiex_assoc_event *event; switch (eventcause) { case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: @@ -404,53 +402,6 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_HOSTWAKE_STAIE: dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause); break; - - case EVENT_UAP_STA_ASSOC: - skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); - memset(&sinfo, 0, sizeof(sinfo)); - event = (struct mwifiex_assoc_event *)adapter->event_skb->data; - if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) { - len = -1; - - if (ieee80211_is_assoc_req(event->frame_control)) - len = 0; - else if (ieee80211_is_reassoc_req(event->frame_control)) - /* There will be ETH_ALEN bytes of - * current_ap_addr before the re-assoc ies. - */ - len = ETH_ALEN; - - if (len != -1) { - sinfo.filled = STATION_INFO_ASSOC_REQ_IES; - sinfo.assoc_req_ies = (u8 *)&event->data[len]; - len = (u8 *)sinfo.assoc_req_ies - - (u8 *)&event->frame_control; - sinfo.assoc_req_ies_len = - le16_to_cpu(event->len) - (u16)len; - } - } - cfg80211_new_sta(priv->netdev, event->sta_addr, &sinfo, - GFP_KERNEL); - break; - case EVENT_UAP_STA_DEAUTH: - skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); - cfg80211_del_sta(priv->netdev, adapter->event_skb->data, - GFP_KERNEL); - break; - case EVENT_UAP_BSS_IDLE: - priv->media_connected = false; - break; - case EVENT_UAP_BSS_ACTIVE: - priv->media_connected = true; - break; - case EVENT_UAP_BSS_START: - dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause); - memcpy(priv->netdev->dev_addr, adapter->event_body+2, ETH_ALEN); - break; - case EVENT_UAP_MIC_COUNTERMEASURES: - /* For future development */ - dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause); - break; default: dev_dbg(adapter->dev, "event: unknown event id: %#x\n", eventcause); diff --git a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c index 106c449477b2..58970e0f7d13 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -462,7 +462,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, info->bss_chan = bss_desc->channel; - memcpy(info->country_code, adapter->country_code, + memcpy(info->country_code, priv->country_code, IEEE80211_COUNTRY_STRING_LEN); info->media_connected = priv->media_connected; @@ -1219,8 +1219,7 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version, * with requisite parameters and calls the IOCTL handler. */ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, - int key_len, u8 key_index, - const u8 *mac_addr, int disable) + int key_len, u8 key_index, int disable) { struct mwifiex_ds_encrypt_key encrypt_key; @@ -1230,12 +1229,8 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, encrypt_key.key_index = key_index; if (key_len) memcpy(encrypt_key.key_material, key, key_len); - if (mac_addr) - memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN); } else { encrypt_key.key_disable = true; - if (mac_addr) - memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN); } return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key); diff --git a/trunk/drivers/net/wireless/mwifiex/uap_cmd.c b/trunk/drivers/net/wireless/mwifiex/uap_cmd.c deleted file mode 100644 index 76dfbc42a732..000000000000 --- a/trunk/drivers/net/wireless/mwifiex/uap_cmd.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Marvell Wireless LAN device driver: AP specific command handling - * - * Copyright (C) 2012, Marvell International Ltd. - * - * This software file (the "File") is distributed by Marvell International - * Ltd. under the terms of the GNU General Public License Version 2, June 1991 - * (the "License"). You may use, redistribute and/or modify this File in - * accordance with the terms and conditions of the License, a copy of which - * is available by writing to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the - * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. - * - * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE - * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE - * ARE EXPRESSLY DISCLAIMED. The License provides additional details about - * this warranty disclaimer. - */ - -#include "main.h" - -/* This function parses security related parameters from cfg80211_ap_settings - * and sets into FW understandable bss_config structure. - */ -int mwifiex_set_secure_params(struct mwifiex_private *priv, - struct mwifiex_uap_bss_param *bss_config, - struct cfg80211_ap_settings *params) { - int i; - - switch (params->auth_type) { - case NL80211_AUTHTYPE_OPEN_SYSTEM: - bss_config->auth_mode = WLAN_AUTH_OPEN; - break; - case NL80211_AUTHTYPE_SHARED_KEY: - bss_config->auth_mode = WLAN_AUTH_SHARED_KEY; - break; - case NL80211_AUTHTYPE_NETWORK_EAP: - bss_config->auth_mode = WLAN_AUTH_LEAP; - break; - default: - bss_config->auth_mode = MWIFIEX_AUTH_MODE_AUTO; - break; - } - - bss_config->key_mgmt_operation |= KEY_MGMT_ON_HOST; - - for (i = 0; i < params->crypto.n_akm_suites; i++) { - switch (params->crypto.akm_suites[i]) { - case WLAN_AKM_SUITE_8021X: - if (params->crypto.wpa_versions & - NL80211_WPA_VERSION_1) { - bss_config->protocol = PROTOCOL_WPA; - bss_config->key_mgmt = KEY_MGMT_EAP; - } - if (params->crypto.wpa_versions & - NL80211_WPA_VERSION_2) { - bss_config->protocol = PROTOCOL_WPA2; - bss_config->key_mgmt = KEY_MGMT_EAP; - } - break; - case WLAN_AKM_SUITE_PSK: - if (params->crypto.wpa_versions & - NL80211_WPA_VERSION_1) { - bss_config->protocol = PROTOCOL_WPA; - bss_config->key_mgmt = KEY_MGMT_PSK; - } - if (params->crypto.wpa_versions & - NL80211_WPA_VERSION_2) { - bss_config->protocol = PROTOCOL_WPA2; - bss_config->key_mgmt = KEY_MGMT_PSK; - } - break; - default: - break; - } - } - for (i = 0; i < params->crypto.n_ciphers_pairwise; i++) { - switch (params->crypto.ciphers_pairwise[i]) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - break; - case WLAN_CIPHER_SUITE_TKIP: - bss_config->wpa_cfg.pairwise_cipher_wpa = CIPHER_TKIP; - break; - case WLAN_CIPHER_SUITE_CCMP: - bss_config->wpa_cfg.pairwise_cipher_wpa2 = - CIPHER_AES_CCMP; - default: - break; - } - } - - switch (params->crypto.cipher_group) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - break; - case WLAN_CIPHER_SUITE_TKIP: - bss_config->wpa_cfg.group_cipher = CIPHER_TKIP; - break; - case WLAN_CIPHER_SUITE_CCMP: - bss_config->wpa_cfg.group_cipher = CIPHER_AES_CCMP; - break; - default: - break; - } - - return 0; -} - -/* This function initializes some of mwifiex_uap_bss_param variables. - * This helps FW in ignoring invalid values. These values may or may not - * be get updated to valid ones at later stage. - */ -void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config) -{ - config->bcast_ssid_ctl = 0x7F; - config->radio_ctl = 0x7F; - config->dtim_period = 0x7F; - config->beacon_period = 0x7FFF; - config->auth_mode = 0x7F; - config->rts_threshold = 0x7FFF; - config->frag_threshold = 0x7FFF; - config->retry_limit = 0x7F; -} - -/* This function parses BSS related parameters from structure - * and prepares TLVs. These TLVs are appended to command buffer. -*/ -static int -mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) -{ - struct host_cmd_tlv_dtim_period *dtim_period; - struct host_cmd_tlv_beacon_period *beacon_period; - struct host_cmd_tlv_ssid *ssid; - struct host_cmd_tlv_channel_band *chan_band; - struct host_cmd_tlv_frag_threshold *frag_threshold; - struct host_cmd_tlv_rts_threshold *rts_threshold; - struct host_cmd_tlv_retry_limit *retry_limit; - struct host_cmd_tlv_pwk_cipher *pwk_cipher; - struct host_cmd_tlv_gwk_cipher *gwk_cipher; - struct host_cmd_tlv_encrypt_protocol *encrypt_protocol; - struct host_cmd_tlv_auth_type *auth_type; - struct host_cmd_tlv_passphrase *passphrase; - struct host_cmd_tlv_akmp *tlv_akmp; - struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; - u16 cmd_size = *param_size; - - if (bss_cfg->ssid.ssid_len) { - ssid = (struct host_cmd_tlv_ssid *)tlv; - ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_SSID); - ssid->tlv.len = cpu_to_le16((u16)bss_cfg->ssid.ssid_len); - memcpy(ssid->ssid, bss_cfg->ssid.ssid, bss_cfg->ssid.ssid_len); - cmd_size += sizeof(struct host_cmd_tlv) + - bss_cfg->ssid.ssid_len; - tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len; - } - if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) { - chan_band = (struct host_cmd_tlv_channel_band *)tlv; - chan_band->tlv.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST); - chan_band->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_channel_band) - - sizeof(struct host_cmd_tlv)); - chan_band->band_config = bss_cfg->band_cfg; - chan_band->channel = bss_cfg->channel; - cmd_size += sizeof(struct host_cmd_tlv_channel_band); - tlv += sizeof(struct host_cmd_tlv_channel_band); - } - if (bss_cfg->beacon_period >= MIN_BEACON_PERIOD && - bss_cfg->beacon_period <= MAX_BEACON_PERIOD) { - beacon_period = (struct host_cmd_tlv_beacon_period *)tlv; - beacon_period->tlv.type = - cpu_to_le16(TLV_TYPE_UAP_BEACON_PERIOD); - beacon_period->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_beacon_period) - - sizeof(struct host_cmd_tlv)); - beacon_period->period = cpu_to_le16(bss_cfg->beacon_period); - cmd_size += sizeof(struct host_cmd_tlv_beacon_period); - tlv += sizeof(struct host_cmd_tlv_beacon_period); - } - if (bss_cfg->dtim_period >= MIN_DTIM_PERIOD && - bss_cfg->dtim_period <= MAX_DTIM_PERIOD) { - dtim_period = (struct host_cmd_tlv_dtim_period *)tlv; - dtim_period->tlv.type = cpu_to_le16(TLV_TYPE_UAP_DTIM_PERIOD); - dtim_period->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_dtim_period) - - sizeof(struct host_cmd_tlv)); - dtim_period->period = bss_cfg->dtim_period; - cmd_size += sizeof(struct host_cmd_tlv_dtim_period); - tlv += sizeof(struct host_cmd_tlv_dtim_period); - } - if (bss_cfg->rts_threshold <= MWIFIEX_RTS_MAX_VALUE) { - rts_threshold = (struct host_cmd_tlv_rts_threshold *)tlv; - rts_threshold->tlv.type = - cpu_to_le16(TLV_TYPE_UAP_RTS_THRESHOLD); - rts_threshold->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_rts_threshold) - - sizeof(struct host_cmd_tlv)); - rts_threshold->rts_thr = cpu_to_le16(bss_cfg->rts_threshold); - cmd_size += sizeof(struct host_cmd_tlv_frag_threshold); - tlv += sizeof(struct host_cmd_tlv_frag_threshold); - } - if ((bss_cfg->frag_threshold >= MWIFIEX_FRAG_MIN_VALUE) && - (bss_cfg->frag_threshold <= MWIFIEX_FRAG_MAX_VALUE)) { - frag_threshold = (struct host_cmd_tlv_frag_threshold *)tlv; - frag_threshold->tlv.type = - cpu_to_le16(TLV_TYPE_UAP_FRAG_THRESHOLD); - frag_threshold->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_frag_threshold) - - sizeof(struct host_cmd_tlv)); - frag_threshold->frag_thr = cpu_to_le16(bss_cfg->frag_threshold); - cmd_size += sizeof(struct host_cmd_tlv_frag_threshold); - tlv += sizeof(struct host_cmd_tlv_frag_threshold); - } - if (bss_cfg->retry_limit <= MWIFIEX_RETRY_LIMIT) { - retry_limit = (struct host_cmd_tlv_retry_limit *)tlv; - retry_limit->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RETRY_LIMIT); - retry_limit->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_retry_limit) - - sizeof(struct host_cmd_tlv)); - retry_limit->limit = (u8)bss_cfg->retry_limit; - cmd_size += sizeof(struct host_cmd_tlv_retry_limit); - tlv += sizeof(struct host_cmd_tlv_retry_limit); - } - if ((bss_cfg->protocol & PROTOCOL_WPA) || - (bss_cfg->protocol & PROTOCOL_WPA2) || - (bss_cfg->protocol & PROTOCOL_EAP)) { - tlv_akmp = (struct host_cmd_tlv_akmp *)tlv; - tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP); - tlv_akmp->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) - - sizeof(struct host_cmd_tlv)); - tlv_akmp->key_mgmt_operation = - cpu_to_le16(bss_cfg->key_mgmt_operation); - tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt); - cmd_size += sizeof(struct host_cmd_tlv_akmp); - tlv += sizeof(struct host_cmd_tlv_akmp); - - if (bss_cfg->wpa_cfg.pairwise_cipher_wpa & - VALID_CIPHER_BITMAP) { - pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; - pwk_cipher->tlv.type = - cpu_to_le16(TLV_TYPE_PWK_CIPHER); - pwk_cipher->tlv.len = cpu_to_le16( - sizeof(struct host_cmd_tlv_pwk_cipher) - - sizeof(struct host_cmd_tlv)); - pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA); - pwk_cipher->cipher = - bss_cfg->wpa_cfg.pairwise_cipher_wpa; - cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); - tlv += sizeof(struct host_cmd_tlv_pwk_cipher); - } - if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 & - VALID_CIPHER_BITMAP) { - pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; - pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER); - pwk_cipher->tlv.len = cpu_to_le16( - sizeof(struct host_cmd_tlv_pwk_cipher) - - sizeof(struct host_cmd_tlv)); - pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2); - pwk_cipher->cipher = - bss_cfg->wpa_cfg.pairwise_cipher_wpa2; - cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); - tlv += sizeof(struct host_cmd_tlv_pwk_cipher); - } - if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) { - gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv; - gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER); - gwk_cipher->tlv.len = cpu_to_le16( - sizeof(struct host_cmd_tlv_gwk_cipher) - - sizeof(struct host_cmd_tlv)); - gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher; - cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher); - tlv += sizeof(struct host_cmd_tlv_gwk_cipher); - } - if (bss_cfg->wpa_cfg.length) { - passphrase = (struct host_cmd_tlv_passphrase *)tlv; - passphrase->tlv.type = - cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE); - passphrase->tlv.len = - cpu_to_le16(bss_cfg->wpa_cfg.length); - memcpy(passphrase->passphrase, - bss_cfg->wpa_cfg.passphrase, - bss_cfg->wpa_cfg.length); - cmd_size += sizeof(struct host_cmd_tlv) + - bss_cfg->wpa_cfg.length; - tlv += sizeof(struct host_cmd_tlv) + - bss_cfg->wpa_cfg.length; - } - } - if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) || - (bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) { - auth_type = (struct host_cmd_tlv_auth_type *)tlv; - auth_type->tlv.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); - auth_type->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_auth_type) - - sizeof(struct host_cmd_tlv)); - auth_type->auth_type = (u8)bss_cfg->auth_mode; - cmd_size += sizeof(struct host_cmd_tlv_auth_type); - tlv += sizeof(struct host_cmd_tlv_auth_type); - } - if (bss_cfg->protocol) { - encrypt_protocol = (struct host_cmd_tlv_encrypt_protocol *)tlv; - encrypt_protocol->tlv.type = - cpu_to_le16(TLV_TYPE_UAP_ENCRY_PROTOCOL); - encrypt_protocol->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_encrypt_protocol) - - sizeof(struct host_cmd_tlv)); - encrypt_protocol->proto = cpu_to_le16(bss_cfg->protocol); - cmd_size += sizeof(struct host_cmd_tlv_encrypt_protocol); - tlv += sizeof(struct host_cmd_tlv_encrypt_protocol); - } - - *param_size = cmd_size; - - return 0; -} - -/* This function parses custom IEs from IE list and prepares command buffer */ -static int mwifiex_uap_custom_ie_prepare(u8 *tlv, void *cmd_buf, u16 *ie_size) -{ - struct mwifiex_ie_list *ap_ie = cmd_buf; - struct host_cmd_tlv *tlv_ie = (struct host_cmd_tlv *)tlv; - - if (!ap_ie || !ap_ie->len || !ap_ie->ie_list) - return -1; - - *ie_size += le16_to_cpu(ap_ie->len) + sizeof(struct host_cmd_tlv); - - tlv_ie->type = cpu_to_le16(TLV_TYPE_MGMT_IE); - tlv_ie->len = ap_ie->len; - tlv += sizeof(struct host_cmd_tlv); - - memcpy(tlv, ap_ie->ie_list, le16_to_cpu(ap_ie->len)); - - return 0; -} - -/* Parse AP config structure and prepare TLV based command structure - * to be sent to FW for uAP configuration - */ -static int -mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd, u16 cmd_action, - u32 type, void *cmd_buf) -{ - u8 *tlv; - u16 cmd_size, param_size, ie_size; - struct host_cmd_ds_sys_config *sys_cfg; - - cmd->command = cpu_to_le16(HostCmd_CMD_UAP_SYS_CONFIG); - cmd_size = (u16)(sizeof(struct host_cmd_ds_sys_config) + S_DS_GEN); - sys_cfg = (struct host_cmd_ds_sys_config *)&cmd->params.uap_sys_config; - sys_cfg->action = cpu_to_le16(cmd_action); - tlv = sys_cfg->tlv; - - switch (type) { - case UAP_BSS_PARAMS_I: - param_size = cmd_size; - if (mwifiex_uap_bss_param_prepare(tlv, cmd_buf, ¶m_size)) - return -1; - cmd->size = cpu_to_le16(param_size); - break; - case UAP_CUSTOM_IE_I: - ie_size = cmd_size; - if (mwifiex_uap_custom_ie_prepare(tlv, cmd_buf, &ie_size)) - return -1; - cmd->size = cpu_to_le16(ie_size); - break; - default: - return -1; - } - - return 0; -} - -/* This function prepares the AP specific commands before sending them - * to the firmware. - * This is a generic function which calls specific command preparation - * routines based upon the command number. - */ -int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no, - u16 cmd_action, u32 type, - void *data_buf, void *cmd_buf) -{ - struct host_cmd_ds_command *cmd = cmd_buf; - - switch (cmd_no) { - case HostCmd_CMD_UAP_SYS_CONFIG: - if (mwifiex_cmd_uap_sys_config(cmd, cmd_action, type, data_buf)) - return -1; - break; - case HostCmd_CMD_UAP_BSS_START: - case HostCmd_CMD_UAP_BSS_STOP: - cmd->command = cpu_to_le16(cmd_no); - cmd->size = cpu_to_le16(S_DS_GEN); - break; - default: - dev_err(priv->adapter->dev, - "PREP_CMD: unknown cmd %#x\n", cmd_no); - return -1; - } - - return 0; -} - -/* This function sets the RF channel for AP. - * - * This function populates channel information in AP config structure - * and sends command to configure channel information in AP. - */ -int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel) -{ - struct mwifiex_uap_bss_param *bss_cfg; - struct wiphy *wiphy = priv->wdev->wiphy; - - bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL); - if (!bss_cfg) - return -ENOMEM; - - bss_cfg->band_cfg = BAND_CONFIG_MANUAL; - bss_cfg->channel = channel; - - if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG, - HostCmd_ACT_GEN_SET, - UAP_BSS_PARAMS_I, bss_cfg)) { - wiphy_err(wiphy, "Failed to set the uAP channel\n"); - kfree(bss_cfg); - return -1; - } - - kfree(bss_cfg); - return 0; -} diff --git a/trunk/drivers/net/wireless/mwifiex/wmm.c b/trunk/drivers/net/wireless/mwifiex/wmm.c index f3fc65515857..429a1dee2d26 100644 --- a/trunk/drivers/net/wireless/mwifiex/wmm.c +++ b/trunk/drivers/net/wireless/mwifiex/wmm.c @@ -885,10 +885,6 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, tid_ptr = &(priv_tmp)->wmm. tid_tbl_ptr[tos_to_tid[i]]; - /* For non-STA ra_list_curr may be NULL */ - if (!tid_ptr->ra_list_curr) - continue; - spin_lock_irqsave(&tid_ptr->tid_tbl_lock, flags); is_list_empty = diff --git a/trunk/drivers/net/wireless/rndis_wlan.c b/trunk/drivers/net/wireless/rndis_wlan.c index 8b2226262524..d66e2980bc27 100644 --- a/trunk/drivers/net/wireless/rndis_wlan.c +++ b/trunk/drivers/net/wireless/rndis_wlan.c @@ -554,6 +554,9 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev, static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev); +static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, enum nl80211_channel_type channel_type); + static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); @@ -595,6 +598,7 @@ static const struct cfg80211_ops rndis_config_ops = { .disconnect = rndis_disconnect, .join_ibss = rndis_join_ibss, .leave_ibss = rndis_leave_ibss, + .set_channel = rndis_set_channel, .add_key = rndis_add_key, .del_key = rndis_del_key, .set_default_key = rndis_set_default_key, @@ -2419,6 +2423,16 @@ static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev) return deauthenticate(usbdev); } +static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev, + struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) +{ + struct rndis_wlan_private *priv = wiphy_priv(wiphy); + struct usbnet *usbdev = priv->usbdev; + + return set_channel(usbdev, + ieee80211_frequency_to_channel(chan->center_freq)); +} + static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c index cad25bfebd7a..931331d95217 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1192,7 +1192,6 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1814, 0x5390) }, { PCI_DEVICE(0x1814, 0x5392) }, { PCI_DEVICE(0x1814, 0x539a) }, - { PCI_DEVICE(0x1814, 0x539b) }, { PCI_DEVICE(0x1814, 0x539f) }, #endif { 0, } diff --git a/trunk/drivers/net/wireless/ti/wl12xx/Kconfig b/trunk/drivers/net/wireless/ti/wl12xx/Kconfig index c2183594655a..5b92329122c4 100644 --- a/trunk/drivers/net/wireless/ti/wl12xx/Kconfig +++ b/trunk/drivers/net/wireless/ti/wl12xx/Kconfig @@ -1,6 +1,5 @@ config WL12XX tristate "TI wl12xx support" - depends on MAC80211 select WLCORE ---help--- This module adds support for wireless adapters based on TI wl1271, diff --git a/trunk/drivers/net/wireless/ti/wlcore/Kconfig b/trunk/drivers/net/wireless/ti/wlcore/Kconfig index 54156b0b5c2d..9d04c38938bc 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/Kconfig +++ b/trunk/drivers/net/wireless/ti/wlcore/Kconfig @@ -1,6 +1,6 @@ config WLCORE tristate "TI wlcore support" - depends on WL_TI && GENERIC_HARDIRQS && MAC80211 + depends on WL_TI && GENERIC_HARDIRQS depends on INET select FW_LOADER ---help--- diff --git a/trunk/drivers/net/wireless/ti/wlcore/acx.c b/trunk/drivers/net/wireless/ti/wlcore/acx.c index 509aa881d790..5912541a925e 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/acx.c +++ b/trunk/drivers/net/wireless/ti/wlcore/acx.c @@ -1714,83 +1714,3 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl) return ret; } - -/* Set the global behaviour of RX filters - On/Off + default action */ -int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, - enum rx_filter_action action) -{ - struct acx_default_rx_filter *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx default rx filter en: %d act: %d", - enable, action); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) - return -ENOMEM; - - acx->enable = enable; - acx->default_action = action; - - ret = wl1271_cmd_configure(wl, ACX_ENABLE_RX_DATA_FILTER, acx, - sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx default rx filter enable failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -/* Configure or disable a specific RX filter pattern */ -int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable, - struct wl12xx_rx_filter *filter) -{ - struct acx_rx_filter_cfg *acx; - int fields_size = 0; - int acx_size; - int ret; - - WARN_ON(enable && !filter); - WARN_ON(index >= WL1271_MAX_RX_FILTERS); - - wl1271_debug(DEBUG_ACX, - "acx set rx filter idx: %d enable: %d filter: %p", - index, enable, filter); - - if (enable) { - fields_size = wl1271_rx_filter_get_fields_size(filter); - - wl1271_debug(DEBUG_ACX, "act: %d num_fields: %d field_size: %d", - filter->action, filter->num_fields, fields_size); - } - - acx_size = ALIGN(sizeof(*acx) + fields_size, 4); - acx = kzalloc(acx_size, GFP_KERNEL); - - if (!acx) - return -ENOMEM; - - acx->enable = enable; - acx->index = index; - - if (enable) { - acx->num_fields = filter->num_fields; - acx->action = filter->action; - wl1271_rx_filter_flatten_fields(filter, acx->fields); - } - - wl1271_dump(DEBUG_ACX, "RX_FILTER: ", acx, acx_size); - - ret = wl1271_cmd_configure(wl, ACX_SET_RX_DATA_FILTER, acx, acx_size); - if (ret < 0) { - wl1271_warning("setting rx filter failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} diff --git a/trunk/drivers/net/wireless/ti/wlcore/acx.h b/trunk/drivers/net/wireless/ti/wlcore/acx.h index 8106b2ebfe60..b2f88831b7a9 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/acx.h +++ b/trunk/drivers/net/wireless/ti/wlcore/acx.h @@ -1147,32 +1147,6 @@ struct wl12xx_acx_config_hangover { u8 padding[2]; } __packed; - -struct acx_default_rx_filter { - struct acx_header header; - u8 enable; - - /* action of type FILTER_XXX */ - u8 default_action; - - u8 pad[2]; -} __packed; - - -struct acx_rx_filter_cfg { - struct acx_header header; - - u8 enable; - - /* 0 - WL1271_MAX_RX_FILTERS-1 */ - u8 index; - - u8 action; - - u8 num_fields; - u8 fields[0]; -} __packed; - enum { ACX_WAKE_UP_CONDITIONS = 0x0000, ACX_MEM_CFG = 0x0001, @@ -1330,9 +1304,5 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); int wl1271_acx_fm_coex(struct wl1271 *wl); int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl); int wl12xx_acx_config_hangover(struct wl1271 *wl); -int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, - enum rx_filter_action action); -int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable, - struct wl12xx_rx_filter *filter); #endif /* __WL1271_ACX_H__ */ diff --git a/trunk/drivers/net/wireless/ti/wlcore/boot.c b/trunk/drivers/net/wireless/ti/wlcore/boot.c index 9b98230f84ce..3a2207db5405 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/boot.c +++ b/trunk/drivers/net/wireless/ti/wlcore/boot.c @@ -72,7 +72,7 @@ static int wlcore_boot_fw_version(struct wl1271 *wl) struct wl1271_static_data *static_data; int ret; - static_data = kmalloc(sizeof(*static_data), GFP_KERNEL | GFP_DMA); + static_data = kmalloc(sizeof(*static_data), GFP_DMA); if (!static_data) { wl1271_error("Couldn't allocate memory for static data!"); return -ENOMEM; @@ -413,7 +413,6 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) /* unmask required mbox events */ wl->event_mask = BSS_LOSE_EVENT_ID | - REGAINED_BSS_EVENT_ID | SCAN_COMPLETE_EVENT_ID | ROLE_STOP_COMPLETE_EVENT_ID | RSSI_SNR_TRIGGER_0_EVENT_ID | diff --git a/trunk/drivers/net/wireless/ti/wlcore/cmd.c b/trunk/drivers/net/wireless/ti/wlcore/cmd.c index 5b128a971449..5c4716c6f040 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/cmd.c +++ b/trunk/drivers/net/wireless/ti/wlcore/cmd.c @@ -123,9 +123,7 @@ static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask) unsigned long timeout; int ret = 0; - events_vector = kmalloc(sizeof(*events_vector), GFP_KERNEL | GFP_DMA); - if (!events_vector) - return -ENOMEM; + events_vector = kmalloc(sizeof(*events_vector), GFP_DMA); timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); @@ -1036,7 +1034,7 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif) skb_reserve(skb, sizeof(*hdr) + WL1271_EXTRA_SPACE_MAX); tmpl = (struct wl12xx_arp_rsp_template *)skb_put(skb, sizeof(*tmpl)); - memset(tmpl, 0, sizeof(*tmpl)); + memset(tmpl, 0, sizeof(tmpl)); /* llc layer */ memcpy(tmpl->llc_hdr, rfc1042_header, sizeof(rfc1042_header)); @@ -1085,7 +1083,7 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif) /* mac80211 header */ hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, sizeof(*hdr)); - memset(hdr, 0, sizeof(*hdr)); + memset(hdr, 0, sizeof(hdr)); fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS; if (wlvif->sta.qos) fc |= IEEE80211_STYPE_QOS_DATA; diff --git a/trunk/drivers/net/wireless/ti/wlcore/event.c b/trunk/drivers/net/wireless/ti/wlcore/event.c index 28e2a633c3be..292632ddf890 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/event.c +++ b/trunk/drivers/net/wireless/ti/wlcore/event.c @@ -103,6 +103,7 @@ static int wl1271_event_process(struct wl1271 *wl) struct ieee80211_vif *vif; struct wl12xx_vif *wlvif; u32 vector; + bool beacon_loss = false; bool disconnect_sta = false; unsigned long sta_bitmap = 0; @@ -140,23 +141,20 @@ static int wl1271_event_process(struct wl1271 *wl) mbox->soft_gemini_sense_info); /* - * We are HW_MONITOR device. On beacon loss - queue - * connection loss work. Cancel it on REGAINED event. + * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon + * filtering) is enabled. Without PSM, the stack will receive all + * beacons and can detect beacon loss by itself. + * + * As there's possibility that the driver disables PSM before receiving + * BSS_LOSE_EVENT, beacon loss has to be reported to the stack. + * */ if (vector & BSS_LOSE_EVENT_ID) { /* TODO: check for multi-role */ - int delay = wl->conf.conn.synch_fail_thold * - wl->conf.conn.bss_lose_timeout; wl1271_info("Beacon loss detected."); - cancel_delayed_work_sync(&wl->connection_loss_work); - ieee80211_queue_delayed_work(wl->hw, &wl->connection_loss_work, - msecs_to_jiffies(delay)); - } - if (vector & REGAINED_BSS_EVENT_ID) { - /* TODO: check for multi-role */ - wl1271_info("Beacon regained."); - cancel_delayed_work_sync(&wl->connection_loss_work); + /* indicate to the stack, that beacons have been lost */ + beacon_loss = true; } if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { @@ -259,6 +257,13 @@ static int wl1271_event_process(struct wl1271 *wl) rcu_read_unlock(); } } + + if (beacon_loss) + wl12xx_for_each_wlvif_sta(wl, wlvif) { + vif = wl12xx_wlvif_to_vif(wlvif); + ieee80211_connection_loss(vif); + } + return 0; } diff --git a/trunk/drivers/net/wireless/ti/wlcore/main.c b/trunk/drivers/net/wireless/ti/wlcore/main.c index acef93390d3d..2b0f987660c6 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/main.c +++ b/trunk/drivers/net/wireless/ti/wlcore/main.c @@ -1120,7 +1120,6 @@ int wl1271_plt_stop(struct wl1271 *wl) cancel_work_sync(&wl->recovery_work); cancel_delayed_work_sync(&wl->elp_work); cancel_delayed_work_sync(&wl->tx_watchdog_work); - cancel_delayed_work_sync(&wl->connection_loss_work); mutex_lock(&wl->mutex); wl1271_power_off(wl); @@ -1262,270 +1261,8 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl) #ifdef CONFIG_PM -static int -wl1271_validate_wowlan_pattern(struct cfg80211_wowlan_trig_pkt_pattern *p) -{ - int num_fields = 0, in_field = 0, fields_size = 0; - int i, pattern_len = 0; - - if (!p->mask) { - wl1271_warning("No mask in WoWLAN pattern"); - return -EINVAL; - } - - /* - * The pattern is broken up into segments of bytes at different offsets - * that need to be checked by the FW filter. Each segment is called - * a field in the FW API. We verify that the total number of fields - * required for this pattern won't exceed FW limits (8) - * as well as the total fields buffer won't exceed the FW limit. - * Note that if there's a pattern which crosses Ethernet/IP header - * boundary a new field is required. - */ - for (i = 0; i < p->pattern_len; i++) { - if (test_bit(i, (unsigned long *)p->mask)) { - if (!in_field) { - in_field = 1; - pattern_len = 1; - } else { - if (i == WL1271_RX_FILTER_ETH_HEADER_SIZE) { - num_fields++; - fields_size += pattern_len + - RX_FILTER_FIELD_OVERHEAD; - pattern_len = 1; - } else - pattern_len++; - } - } else { - if (in_field) { - in_field = 0; - fields_size += pattern_len + - RX_FILTER_FIELD_OVERHEAD; - num_fields++; - } - } - } - - if (in_field) { - fields_size += pattern_len + RX_FILTER_FIELD_OVERHEAD; - num_fields++; - } - - if (num_fields > WL1271_RX_FILTER_MAX_FIELDS) { - wl1271_warning("RX Filter too complex. Too many segments"); - return -EINVAL; - } - - if (fields_size > WL1271_RX_FILTER_MAX_FIELDS_SIZE) { - wl1271_warning("RX filter pattern is too big"); - return -E2BIG; - } - - return 0; -} - -struct wl12xx_rx_filter *wl1271_rx_filter_alloc(void) -{ - return kzalloc(sizeof(struct wl12xx_rx_filter), GFP_KERNEL); -} - -void wl1271_rx_filter_free(struct wl12xx_rx_filter *filter) -{ - int i; - - if (filter == NULL) - return; - - for (i = 0; i < filter->num_fields; i++) - kfree(filter->fields[i].pattern); - - kfree(filter); -} - -int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter, - u16 offset, u8 flags, - u8 *pattern, u8 len) -{ - struct wl12xx_rx_filter_field *field; - - if (filter->num_fields == WL1271_RX_FILTER_MAX_FIELDS) { - wl1271_warning("Max fields per RX filter. can't alloc another"); - return -EINVAL; - } - - field = &filter->fields[filter->num_fields]; - - field->pattern = kzalloc(len, GFP_KERNEL); - if (!field->pattern) { - wl1271_warning("Failed to allocate RX filter pattern"); - return -ENOMEM; - } - - filter->num_fields++; - - field->offset = cpu_to_le16(offset); - field->flags = flags; - field->len = len; - memcpy(field->pattern, pattern, len); - - return 0; -} - -int wl1271_rx_filter_get_fields_size(struct wl12xx_rx_filter *filter) -{ - int i, fields_size = 0; - - for (i = 0; i < filter->num_fields; i++) - fields_size += filter->fields[i].len + - sizeof(struct wl12xx_rx_filter_field) - - sizeof(u8 *); - - return fields_size; -} - -void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter, - u8 *buf) -{ - int i; - struct wl12xx_rx_filter_field *field; - - for (i = 0; i < filter->num_fields; i++) { - field = (struct wl12xx_rx_filter_field *)buf; - - field->offset = filter->fields[i].offset; - field->flags = filter->fields[i].flags; - field->len = filter->fields[i].len; - - memcpy(&field->pattern, filter->fields[i].pattern, field->len); - buf += sizeof(struct wl12xx_rx_filter_field) - - sizeof(u8 *) + field->len; - } -} - -/* - * Allocates an RX filter returned through f - * which needs to be freed using rx_filter_free() - */ -static int wl1271_convert_wowlan_pattern_to_rx_filter( - struct cfg80211_wowlan_trig_pkt_pattern *p, - struct wl12xx_rx_filter **f) -{ - int i, j, ret = 0; - struct wl12xx_rx_filter *filter; - u16 offset; - u8 flags, len; - - filter = wl1271_rx_filter_alloc(); - if (!filter) { - wl1271_warning("Failed to alloc rx filter"); - ret = -ENOMEM; - goto err; - } - - i = 0; - while (i < p->pattern_len) { - if (!test_bit(i, (unsigned long *)p->mask)) { - i++; - continue; - } - - for (j = i; j < p->pattern_len; j++) { - if (!test_bit(j, (unsigned long *)p->mask)) - break; - - if (i < WL1271_RX_FILTER_ETH_HEADER_SIZE && - j >= WL1271_RX_FILTER_ETH_HEADER_SIZE) - break; - } - - if (i < WL1271_RX_FILTER_ETH_HEADER_SIZE) { - offset = i; - flags = WL1271_RX_FILTER_FLAG_ETHERNET_HEADER; - } else { - offset = i - WL1271_RX_FILTER_ETH_HEADER_SIZE; - flags = WL1271_RX_FILTER_FLAG_IP_HEADER; - } - - len = j - i; - - ret = wl1271_rx_filter_alloc_field(filter, - offset, - flags, - &p->pattern[i], len); - if (ret) - goto err; - - i = j; - } - - filter->action = FILTER_SIGNAL; - - *f = filter; - return 0; - -err: - wl1271_rx_filter_free(filter); - *f = NULL; - - return ret; -} - -static int wl1271_configure_wowlan(struct wl1271 *wl, - struct cfg80211_wowlan *wow) -{ - int i, ret; - - if (!wow || wow->any || !wow->n_patterns) { - wl1271_acx_default_rx_filter_enable(wl, 0, FILTER_SIGNAL); - wl1271_rx_filter_clear_all(wl); - return 0; - } - - if (WARN_ON(wow->n_patterns > WL1271_MAX_RX_FILTERS)) - return -EINVAL; - - /* Validate all incoming patterns before clearing current FW state */ - for (i = 0; i < wow->n_patterns; i++) { - ret = wl1271_validate_wowlan_pattern(&wow->patterns[i]); - if (ret) { - wl1271_warning("Bad wowlan pattern %d", i); - return ret; - } - } - - wl1271_acx_default_rx_filter_enable(wl, 0, FILTER_SIGNAL); - wl1271_rx_filter_clear_all(wl); - - /* Translate WoWLAN patterns into filters */ - for (i = 0; i < wow->n_patterns; i++) { - struct cfg80211_wowlan_trig_pkt_pattern *p; - struct wl12xx_rx_filter *filter = NULL; - - p = &wow->patterns[i]; - - ret = wl1271_convert_wowlan_pattern_to_rx_filter(p, &filter); - if (ret) { - wl1271_warning("Failed to create an RX filter from " - "wowlan pattern %d", i); - goto out; - } - - ret = wl1271_rx_filter_enable(wl, i, 1, filter); - - wl1271_rx_filter_free(filter); - if (ret) - goto out; - } - - ret = wl1271_acx_default_rx_filter_enable(wl, 1, FILTER_DROP); - -out: - return ret; -} - static int wl1271_configure_suspend_sta(struct wl1271 *wl, - struct wl12xx_vif *wlvif, - struct cfg80211_wowlan *wow) + struct wl12xx_vif *wlvif) { int ret = 0; @@ -1536,7 +1273,6 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl, if (ret < 0) goto out; - wl1271_configure_wowlan(wl, wow); ret = wl1271_acx_wake_up_conditions(wl, wlvif, wl->conf.conn.suspend_wake_up_event, wl->conf.conn.suspend_listen_interval); @@ -1572,11 +1308,10 @@ static int wl1271_configure_suspend_ap(struct wl1271 *wl, } static int wl1271_configure_suspend(struct wl1271 *wl, - struct wl12xx_vif *wlvif, - struct cfg80211_wowlan *wow) + struct wl12xx_vif *wlvif) { if (wlvif->bss_type == BSS_TYPE_STA_BSS) - return wl1271_configure_suspend_sta(wl, wlvif, wow); + return wl1271_configure_suspend_sta(wl, wlvif); if (wlvif->bss_type == BSS_TYPE_AP_BSS) return wl1271_configure_suspend_ap(wl, wlvif); return 0; @@ -1597,8 +1332,6 @@ static void wl1271_configure_resume(struct wl1271 *wl, return; if (is_sta) { - wl1271_configure_wowlan(wl, NULL); - ret = wl1271_acx_wake_up_conditions(wl, wlvif, wl->conf.conn.wake_up_event, wl->conf.conn.listen_interval); @@ -1622,16 +1355,15 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, int ret; wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); - WARN_ON(!wow); + WARN_ON(!wow || !wow->any); wl1271_tx_flush(wl); mutex_lock(&wl->mutex); wl->wow_enabled = true; wl12xx_for_each_wlvif(wl, wlvif) { - ret = wl1271_configure_suspend(wl, wlvif, wow); + ret = wl1271_configure_suspend(wl, wlvif); if (ret < 0) { - mutex_unlock(&wl->mutex); wl1271_warning("couldn't prepare device to suspend"); return ret; } @@ -1755,7 +1487,6 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) cancel_work_sync(&wl->tx_work); cancel_delayed_work_sync(&wl->elp_work); cancel_delayed_work_sync(&wl->tx_watchdog_work); - cancel_delayed_work_sync(&wl->connection_loss_work); /* let's notify MAC80211 about the remaining pending TX frames */ wl12xx_tx_reset(wl, true); @@ -3708,9 +3439,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, do_join = true; set_assoc = true; - /* Cancel connection_loss_work */ - cancel_delayed_work_sync(&wl->connection_loss_work); - /* * use basic rates from AP, and determine lowest rate * to use with control frames. @@ -4821,34 +4549,6 @@ static struct bin_attribute fwlog_attr = { .read = wl1271_sysfs_read_fwlog, }; -static void wl1271_connection_loss_work(struct work_struct *work) -{ - struct delayed_work *dwork; - struct wl1271 *wl; - struct ieee80211_vif *vif; - struct wl12xx_vif *wlvif; - - dwork = container_of(work, struct delayed_work, work); - wl = container_of(dwork, struct wl1271, connection_loss_work); - - wl1271_info("Connection loss work."); - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - /* Call mac80211 connection loss */ - wl12xx_for_each_wlvif_sta(wl, wlvif) { - if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) - goto out; - vif = wl12xx_wlvif_to_vif(wlvif); - ieee80211_connection_loss(vif); - } -out: - mutex_unlock(&wl->mutex); -} - static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic, int n) { @@ -5104,8 +4804,6 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size) INIT_WORK(&wl->recovery_work, wl1271_recovery_work); INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work); - INIT_DELAYED_WORK(&wl->connection_loss_work, - wl1271_connection_loss_work); wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); if (!wl->freezable_wq) { @@ -5163,7 +4861,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size) goto err_dummy_packet; } - wl->mbox = kmalloc(sizeof(*wl->mbox), GFP_KERNEL | GFP_DMA); + wl->mbox = kmalloc(sizeof(*wl->mbox), GFP_DMA); if (!wl->mbox) { ret = -ENOMEM; goto err_fwlog; @@ -5305,14 +5003,9 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) if (!ret) { wl->irq_wake_enabled = true; device_init_wakeup(wl->dev, 1); - if (pdata->pwr_in_suspend) { + if (pdata->pwr_in_suspend) wl->hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY; - wl->hw->wiphy->wowlan.n_patterns = - WL1271_MAX_RX_FILTERS; - wl->hw->wiphy->wowlan.pattern_min_len = 1; - wl->hw->wiphy->wowlan.pattern_max_len = - WL1271_RX_FILTER_MAX_PATTERN_SIZE; - } + } disable_irq(wl->irq); diff --git a/trunk/drivers/net/wireless/ti/wlcore/rx.c b/trunk/drivers/net/wireless/ti/wlcore/rx.c index 1f1d9488dfb6..89bd9385e90b 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/rx.c +++ b/trunk/drivers/net/wireless/ti/wlcore/rx.c @@ -278,39 +278,3 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status) wl12xx_rearm_rx_streaming(wl, active_hlids); } - -int wl1271_rx_filter_enable(struct wl1271 *wl, - int index, bool enable, - struct wl12xx_rx_filter *filter) -{ - int ret; - - if (wl->rx_filter_enabled[index] == enable) { - wl1271_warning("Request to enable an already " - "enabled rx filter %d", index); - return 0; - } - - ret = wl1271_acx_set_rx_filter(wl, index, enable, filter); - - if (ret) { - wl1271_error("Failed to %s rx data filter %d (err=%d)", - enable ? "enable" : "disable", index, ret); - return ret; - } - - wl->rx_filter_enabled[index] = enable; - - return 0; -} - -void wl1271_rx_filter_clear_all(struct wl1271 *wl) -{ - int i; - - for (i = 0; i < WL1271_MAX_RX_FILTERS; i++) { - if (!wl->rx_filter_enabled[i]) - continue; - wl1271_rx_filter_enable(wl, i, 0, NULL); - } -} diff --git a/trunk/drivers/net/wireless/ti/wlcore/rx.h b/trunk/drivers/net/wireless/ti/wlcore/rx.h index e9a162a864ca..6e129e2a8546 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/rx.h +++ b/trunk/drivers/net/wireless/ti/wlcore/rx.h @@ -138,9 +138,5 @@ struct wl1271_rx_descriptor { void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status); u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); -int wl1271_rx_filter_enable(struct wl1271 *wl, - int index, bool enable, - struct wl12xx_rx_filter *filter); -void wl1271_rx_filter_clear_all(struct wl1271 *wl); #endif diff --git a/trunk/drivers/net/wireless/ti/wlcore/wl12xx.h b/trunk/drivers/net/wireless/ti/wlcore/wl12xx.h index f12bdf745180..a9b220c43e54 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/wl12xx.h +++ b/trunk/drivers/net/wireless/ti/wlcore/wl12xx.h @@ -279,39 +279,6 @@ struct wl1271_link { u8 ba_bitmap; }; -#define WL1271_MAX_RX_FILTERS 5 -#define WL1271_RX_FILTER_MAX_FIELDS 8 - -#define WL1271_RX_FILTER_ETH_HEADER_SIZE 14 -#define WL1271_RX_FILTER_MAX_FIELDS_SIZE 95 -#define RX_FILTER_FIELD_OVERHEAD \ - (sizeof(struct wl12xx_rx_filter_field) - sizeof(u8 *)) -#define WL1271_RX_FILTER_MAX_PATTERN_SIZE \ - (WL1271_RX_FILTER_MAX_FIELDS_SIZE - RX_FILTER_FIELD_OVERHEAD) - -#define WL1271_RX_FILTER_FLAG_MASK BIT(0) -#define WL1271_RX_FILTER_FLAG_IP_HEADER 0 -#define WL1271_RX_FILTER_FLAG_ETHERNET_HEADER BIT(1) - -enum rx_filter_action { - FILTER_DROP = 0, - FILTER_SIGNAL = 1, - FILTER_FW_HANDLE = 2 -}; - -struct wl12xx_rx_filter_field { - __le16 offset; - u8 len; - u8 flags; - u8 *pattern; -} __packed; - -struct wl12xx_rx_filter { - u8 action; - int num_fields; - struct wl12xx_rx_filter_field fields[WL1271_RX_FILTER_MAX_FIELDS]; -}; - struct wl1271_station { u8 hlid; }; @@ -472,14 +439,6 @@ int wl1271_plt_stop(struct wl1271 *wl); int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif); void wl12xx_queue_recovery_work(struct wl1271 *wl); size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen); -int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter, - u16 offset, u8 flags, - u8 *pattern, u8 len); -void wl1271_rx_filter_free(struct wl12xx_rx_filter *filter); -struct wl12xx_rx_filter *wl1271_rx_filter_alloc(void); -int wl1271_rx_filter_get_fields_size(struct wl12xx_rx_filter *filter); -void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter, - u8 *buf); #define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */ diff --git a/trunk/drivers/net/wireless/ti/wlcore/wlcore.h b/trunk/drivers/net/wireless/ti/wlcore/wlcore.h index 0b3f0b586f4b..39f9fadfebd9 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/trunk/drivers/net/wireless/ti/wlcore/wlcore.h @@ -243,9 +243,6 @@ struct wl1271 { struct wl1271_scan scan; struct delayed_work scan_complete_work; - /* Connection loss work */ - struct delayed_work connection_loss_work; - bool sched_scanning; /* The current band */ @@ -352,9 +349,6 @@ struct wl1271 { /* size of the private FW status data */ size_t fw_status_priv_len; - - /* RX Data filter rule state - enabled/disabled */ - bool rx_filter_enabled[WL1271_MAX_RX_FILTERS]; }; int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); diff --git a/trunk/drivers/nfc/Kconfig b/trunk/drivers/nfc/Kconfig index 3b20b73ee649..5af959274d4e 100644 --- a/trunk/drivers/nfc/Kconfig +++ b/trunk/drivers/nfc/Kconfig @@ -17,19 +17,6 @@ config PN544_NFC To compile this driver as a module, choose m here. The module will be called pn544. -config PN544_HCI_NFC - tristate "HCI PN544 NFC driver" - depends on I2C && NFC_SHDLC - select CRC_CCITT - default n - ---help--- - NXP PN544 i2c driver. - This is a driver based on the SHDLC and HCI NFC kernel layers and - will thus not work with NXP libnfc library. - - To compile this driver as a module, choose m here. The module will - be called pn544_hci. - config NFC_PN533 tristate "NXP PN533 USB driver" depends on USB diff --git a/trunk/drivers/nfc/Makefile b/trunk/drivers/nfc/Makefile index 473e44cef612..ab99e8572f02 100644 --- a/trunk/drivers/nfc/Makefile +++ b/trunk/drivers/nfc/Makefile @@ -3,7 +3,6 @@ # obj-$(CONFIG_PN544_NFC) += pn544.o -obj-$(CONFIG_PN544_HCI_NFC) += pn544_hci.o obj-$(CONFIG_NFC_PN533) += pn533.o obj-$(CONFIG_NFC_WILINK) += nfcwilink.o diff --git a/trunk/drivers/nfc/pn533.c b/trunk/drivers/nfc/pn533.c index 19110f0eb15f..e6ec16d92e65 100644 --- a/trunk/drivers/nfc/pn533.c +++ b/trunk/drivers/nfc/pn533.c @@ -394,6 +394,9 @@ static void pn533_wq_cmd_complete(struct work_struct *work) struct pn533_frame *in_frame; int rc; + if (dev == NULL) + return; + in_frame = dev->wq_in_frame; if (dev->wq_in_error) @@ -1191,8 +1194,8 @@ static int pn533_activate_target_nfcdep(struct pn533 *dev) return rc; } -static int pn533_activate_target(struct nfc_dev *nfc_dev, - struct nfc_target *target, u32 protocol) +static int pn533_activate_target(struct nfc_dev *nfc_dev, u32 target_idx, + u32 protocol) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); int rc; @@ -1240,8 +1243,7 @@ static int pn533_activate_target(struct nfc_dev *nfc_dev, return 0; } -static void pn533_deactivate_target(struct nfc_dev *nfc_dev, - struct nfc_target *target) +static void pn533_deactivate_target(struct nfc_dev *nfc_dev, u32 target_idx) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); u8 tg; @@ -1349,7 +1351,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, return 0; } -static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, +static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, u8 comm_mode, u8* gb, size_t gb_len) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); @@ -1550,9 +1552,10 @@ static int pn533_data_exchange_complete(struct pn533 *dev, void *_arg, return 0; } -static int pn533_data_exchange(struct nfc_dev *nfc_dev, - struct nfc_target *target, struct sk_buff *skb, - data_exchange_cb_t cb, void *cb_context) +static int pn533_data_exchange(struct nfc_dev *nfc_dev, u32 target_idx, + struct sk_buff *skb, + data_exchange_cb_t cb, + void *cb_context) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); struct pn533_frame *out_frame, *in_frame; diff --git a/trunk/drivers/nfc/pn544_hci.c b/trunk/drivers/nfc/pn544_hci.c deleted file mode 100644 index 46f4a9f9f5e4..000000000000 --- a/trunk/drivers/nfc/pn544_hci.c +++ /dev/null @@ -1,947 +0,0 @@ -/* - * HCI based Driver for NXP PN544 NFC Chip - * - * Copyright (C) 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#define DRIVER_DESC "HCI NFC driver for PN544" - -#define PN544_HCI_DRIVER_NAME "pn544_hci" - -/* Timing restrictions (ms) */ -#define PN544_HCI_RESETVEN_TIME 30 - -static struct i2c_device_id pn544_hci_id_table[] = { - {"pn544", 0}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, pn544_hci_id_table); - -#define HCI_MODE 0 -#define FW_MODE 1 - -/* framing in HCI mode */ -#define PN544_HCI_LLC_LEN 1 -#define PN544_HCI_LLC_CRC 2 -#define PN544_HCI_LLC_LEN_CRC (PN544_HCI_LLC_LEN + PN544_HCI_LLC_CRC) -#define PN544_HCI_LLC_MIN_SIZE (1 + PN544_HCI_LLC_LEN_CRC) -#define PN544_HCI_LLC_MAX_PAYLOAD 29 -#define PN544_HCI_LLC_MAX_SIZE (PN544_HCI_LLC_LEN_CRC + 1 + \ - PN544_HCI_LLC_MAX_PAYLOAD) - -enum pn544_state { - PN544_ST_COLD, - PN544_ST_FW_READY, - PN544_ST_READY, -}; - -#define FULL_VERSION_LEN 11 - -/* Proprietary commands */ -#define PN544_WRITE 0x3f - -/* Proprietary gates, events, commands and registers */ - -/* NFC_HCI_RF_READER_A_GATE additional registers and commands */ -#define PN544_RF_READER_A_AUTO_ACTIVATION 0x10 -#define PN544_RF_READER_A_CMD_CONTINUE_ACTIVATION 0x12 -#define PN544_MIFARE_CMD 0x21 - -/* Commands that apply to all RF readers */ -#define PN544_RF_READER_CMD_PRESENCE_CHECK 0x30 -#define PN544_RF_READER_CMD_ACTIVATE_NEXT 0x32 - -/* NFC_HCI_ID_MGMT_GATE additional registers */ -#define PN544_ID_MGMT_FULL_VERSION_SW 0x10 - -#define PN544_RF_READER_ISO15693_GATE 0x12 - -#define PN544_RF_READER_F_GATE 0x14 -#define PN544_FELICA_ID 0x04 -#define PN544_FELICA_RAW 0x20 - -#define PN544_RF_READER_JEWEL_GATE 0x15 -#define PN544_JEWEL_RAW_CMD 0x23 - -#define PN544_RF_READER_NFCIP1_INITIATOR_GATE 0x30 -#define PN544_RF_READER_NFCIP1_TARGET_GATE 0x31 - -#define PN544_SYS_MGMT_GATE 0x90 -#define PN544_SYS_MGMT_INFO_NOTIFICATION 0x02 - -#define PN544_POLLING_LOOP_MGMT_GATE 0x94 -#define PN544_PL_RDPHASES 0x06 -#define PN544_PL_EMULATION 0x07 -#define PN544_PL_NFCT_DEACTIVATED 0x09 - -#define PN544_SWP_MGMT_GATE 0xA0 - -#define PN544_NFC_WI_MGMT_GATE 0xA1 - -static u8 pn544_custom_gates[] = { - PN544_SYS_MGMT_GATE, - PN544_SWP_MGMT_GATE, - PN544_POLLING_LOOP_MGMT_GATE, - PN544_NFC_WI_MGMT_GATE, - PN544_RF_READER_F_GATE, - PN544_RF_READER_JEWEL_GATE, - PN544_RF_READER_ISO15693_GATE, - PN544_RF_READER_NFCIP1_INITIATOR_GATE, - PN544_RF_READER_NFCIP1_TARGET_GATE -}; - -/* Largest headroom needed for outgoing custom commands */ -#define PN544_CMDS_HEADROOM 2 - -struct pn544_hci_info { - struct i2c_client *i2c_dev; - struct nfc_shdlc *shdlc; - - enum pn544_state state; - - struct mutex info_lock; - - unsigned int gpio_en; - unsigned int gpio_irq; - unsigned int gpio_fw; - unsigned int en_polarity; - - int hard_fault; /* - * < 0 if hardware error occured (e.g. i2c err) - * and prevents normal operation. - */ -}; - -static void pn544_hci_platform_init(struct pn544_hci_info *info) -{ - int polarity, retry, ret; - char rset_cmd[] = { 0x05, 0xF9, 0x04, 0x00, 0xC3, 0xE5 }; - int count = sizeof(rset_cmd); - - pr_info(DRIVER_DESC ": %s\n", __func__); - dev_info(&info->i2c_dev->dev, "Detecting nfc_en polarity\n"); - - /* Disable fw download */ - gpio_set_value(info->gpio_fw, 0); - - for (polarity = 0; polarity < 2; polarity++) { - info->en_polarity = polarity; - retry = 3; - while (retry--) { - /* power off */ - gpio_set_value(info->gpio_en, !info->en_polarity); - usleep_range(10000, 15000); - - /* power on */ - gpio_set_value(info->gpio_en, info->en_polarity); - usleep_range(10000, 15000); - - /* send reset */ - dev_dbg(&info->i2c_dev->dev, "Sending reset cmd\n"); - ret = i2c_master_send(info->i2c_dev, rset_cmd, count); - if (ret == count) { - dev_info(&info->i2c_dev->dev, - "nfc_en polarity : active %s\n", - (polarity == 0 ? "low" : "high")); - goto out; - } - } - } - - dev_err(&info->i2c_dev->dev, - "Could not detect nfc_en polarity, fallback to active high\n"); - -out: - gpio_set_value(info->gpio_en, !info->en_polarity); -} - -static int pn544_hci_enable(struct pn544_hci_info *info, int mode) -{ - pr_info(DRIVER_DESC ": %s\n", __func__); - - gpio_set_value(info->gpio_fw, 0); - gpio_set_value(info->gpio_en, info->en_polarity); - usleep_range(10000, 15000); - - return 0; -} - -static void pn544_hci_disable(struct pn544_hci_info *info) -{ - pr_info(DRIVER_DESC ": %s\n", __func__); - - gpio_set_value(info->gpio_fw, 0); - gpio_set_value(info->gpio_en, !info->en_polarity); - usleep_range(10000, 15000); - - gpio_set_value(info->gpio_en, info->en_polarity); - usleep_range(10000, 15000); - - gpio_set_value(info->gpio_en, !info->en_polarity); - usleep_range(10000, 15000); -} - -static int pn544_hci_i2c_write(struct i2c_client *client, u8 *buf, int len) -{ - int r; - - usleep_range(3000, 6000); - - r = i2c_master_send(client, buf, len); - - if (r == -EREMOTEIO) { /* Retry, chip was in standby */ - usleep_range(6000, 10000); - r = i2c_master_send(client, buf, len); - } - - if (r >= 0 && r != len) - r = -EREMOTEIO; - - return r; -} - -static int check_crc(u8 *buf, int buflen) -{ - u8 len; - u16 crc; - - len = buf[0] + 1; - crc = crc_ccitt(0xffff, buf, len - 2); - crc = ~crc; - - if (buf[len - 2] != (crc & 0xff) || buf[len - 1] != (crc >> 8)) { - pr_err(PN544_HCI_DRIVER_NAME ": CRC error 0x%x != 0x%x 0x%x\n", - crc, buf[len - 1], buf[len - 2]); - - pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__); - print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, - 16, 2, buf, buflen, false); - return -EPERM; - } - return 0; -} - -/* - * Reads an shdlc frame and returns it in a newly allocated sk_buff. Guarantees - * that i2c bus will be flushed and that next read will start on a new frame. - * returned skb contains only LLC header and payload. - * returns: - * -EREMOTEIO : i2c read error (fatal) - * -EBADMSG : frame was incorrect and discarded - * -ENOMEM : cannot allocate skb, frame dropped - */ -static int pn544_hci_i2c_read(struct i2c_client *client, struct sk_buff **skb) -{ - int r; - u8 len; - u8 tmp[PN544_HCI_LLC_MAX_SIZE - 1]; - - r = i2c_master_recv(client, &len, 1); - if (r != 1) { - dev_err(&client->dev, "cannot read len byte\n"); - return -EREMOTEIO; - } - - if ((len < (PN544_HCI_LLC_MIN_SIZE - 1)) || - (len > (PN544_HCI_LLC_MAX_SIZE - 1))) { - dev_err(&client->dev, "invalid len byte\n"); - r = -EBADMSG; - goto flush; - } - - *skb = alloc_skb(1 + len, GFP_KERNEL); - if (*skb == NULL) { - r = -ENOMEM; - goto flush; - } - - *skb_put(*skb, 1) = len; - - r = i2c_master_recv(client, skb_put(*skb, len), len); - if (r != len) { - kfree_skb(*skb); - return -EREMOTEIO; - } - - r = check_crc((*skb)->data, (*skb)->len); - if (r != 0) { - kfree_skb(*skb); - r = -EBADMSG; - goto flush; - } - - skb_pull(*skb, 1); - skb_trim(*skb, (*skb)->len - 2); - - usleep_range(3000, 6000); - - return 0; - -flush: - if (i2c_master_recv(client, tmp, sizeof(tmp)) < 0) - r = -EREMOTEIO; - - usleep_range(3000, 6000); - - return r; -} - -/* - * Reads an shdlc frame from the chip. This is not as straightforward as it - * seems. There are cases where we could loose the frame start synchronization. - * The frame format is len-data-crc, and corruption can occur anywhere while - * transiting on i2c bus, such that we could read an invalid len. - * In order to recover synchronization with the next frame, we must be sure - * to read the real amount of data without using the len byte. We do this by - * assuming the following: - * - the chip will always present only one single complete frame on the bus - * before triggering the interrupt - * - the chip will not present a new frame until we have completely read - * the previous one (or until we have handled the interrupt). - * The tricky case is when we read a corrupted len that is less than the real - * len. We must detect this here in order to determine that we need to flush - * the bus. This is the reason why we check the crc here. - */ -static irqreturn_t pn544_hci_irq_thread_fn(int irq, void *dev_id) -{ - struct pn544_hci_info *info = dev_id; - struct i2c_client *client = info->i2c_dev; - struct sk_buff *skb = NULL; - int r; - - BUG_ON(!info); - BUG_ON(irq != info->i2c_dev->irq); - - dev_dbg(&client->dev, "IRQ\n"); - - if (info->hard_fault != 0) - return IRQ_HANDLED; - - r = pn544_hci_i2c_read(client, &skb); - if (r == -EREMOTEIO) { - info->hard_fault = r; - - nfc_shdlc_recv_frame(info->shdlc, NULL); - - return IRQ_HANDLED; - } else if ((r == -ENOMEM) || (r == -EBADMSG)) { - return IRQ_HANDLED; - } - - nfc_shdlc_recv_frame(info->shdlc, skb); - - return IRQ_HANDLED; -} - -static int pn544_hci_open(struct nfc_shdlc *shdlc) -{ - struct pn544_hci_info *info = nfc_shdlc_get_clientdata(shdlc); - int r = 0; - - mutex_lock(&info->info_lock); - - if (info->state != PN544_ST_COLD) { - r = -EBUSY; - goto out; - } - - r = pn544_hci_enable(info, HCI_MODE); - -out: - mutex_unlock(&info->info_lock); - return r; -} - -static void pn544_hci_close(struct nfc_shdlc *shdlc) -{ - struct pn544_hci_info *info = nfc_shdlc_get_clientdata(shdlc); - - mutex_lock(&info->info_lock); - - if (info->state == PN544_ST_COLD) - goto out; - - pn544_hci_disable(info); - -out: - mutex_unlock(&info->info_lock); -} - -static int pn544_hci_ready(struct nfc_shdlc *shdlc) -{ - struct nfc_hci_dev *hdev = nfc_shdlc_get_hci_dev(shdlc); - struct sk_buff *skb; - static struct hw_config { - u8 adr[2]; - u8 value; - } hw_config[] = { - {{0x9f, 0x9a}, 0x00}, - - {{0x98, 0x10}, 0xbc}, - - {{0x9e, 0x71}, 0x00}, - - {{0x98, 0x09}, 0x00}, - - {{0x9e, 0xb4}, 0x00}, - - {{0x9e, 0xd9}, 0xff}, - {{0x9e, 0xda}, 0xff}, - {{0x9e, 0xdb}, 0x23}, - {{0x9e, 0xdc}, 0x21}, - {{0x9e, 0xdd}, 0x22}, - {{0x9e, 0xde}, 0x24}, - - {{0x9c, 0x01}, 0x08}, - - {{0x9e, 0xaa}, 0x01}, - - {{0x9b, 0xd1}, 0x0d}, - {{0x9b, 0xd2}, 0x24}, - {{0x9b, 0xd3}, 0x0a}, - {{0x9b, 0xd4}, 0x22}, - {{0x9b, 0xd5}, 0x08}, - {{0x9b, 0xd6}, 0x1e}, - {{0x9b, 0xdd}, 0x1c}, - - {{0x9b, 0x84}, 0x13}, - {{0x99, 0x81}, 0x7f}, - {{0x99, 0x31}, 0x70}, - - {{0x98, 0x00}, 0x3f}, - - {{0x9f, 0x09}, 0x00}, - - {{0x9f, 0x0a}, 0x05}, - - {{0x9e, 0xd1}, 0xa1}, - {{0x99, 0x23}, 0x00}, - - {{0x9e, 0x74}, 0x80}, - - {{0x9f, 0x28}, 0x10}, - - {{0x9f, 0x35}, 0x14}, - - {{0x9f, 0x36}, 0x60}, - - {{0x9c, 0x31}, 0x00}, - - {{0x9c, 0x32}, 0xc8}, - - {{0x9c, 0x19}, 0x40}, - - {{0x9c, 0x1a}, 0x40}, - - {{0x9c, 0x0c}, 0x00}, - - {{0x9c, 0x0d}, 0x00}, - - {{0x9c, 0x12}, 0x00}, - - {{0x9c, 0x13}, 0x00}, - - {{0x98, 0xa2}, 0x0e}, - - {{0x98, 0x93}, 0x40}, - - {{0x98, 0x7d}, 0x02}, - {{0x98, 0x7e}, 0x00}, - {{0x9f, 0xc8}, 0x01}, - }; - struct hw_config *p = hw_config; - int count = ARRAY_SIZE(hw_config); - struct sk_buff *res_skb; - u8 param[4]; - int r; - - param[0] = 0; - while (count--) { - param[1] = p->adr[0]; - param[2] = p->adr[1]; - param[3] = p->value; - - r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE, PN544_WRITE, - param, 4, &res_skb); - if (r < 0) - return r; - - if (res_skb->len != 1) { - kfree_skb(res_skb); - return -EPROTO; - } - - if (res_skb->data[0] != p->value) { - kfree_skb(res_skb); - return -EIO; - } - - kfree_skb(res_skb); - - p++; - } - - param[0] = NFC_HCI_UICC_HOST_ID; - r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE, - NFC_HCI_ADMIN_WHITELIST, param, 1); - if (r < 0) - return r; - - param[0] = 0x3d; - r = nfc_hci_set_param(hdev, PN544_SYS_MGMT_GATE, - PN544_SYS_MGMT_INFO_NOTIFICATION, param, 1); - if (r < 0) - return r; - - param[0] = 0x0; - r = nfc_hci_set_param(hdev, NFC_HCI_RF_READER_A_GATE, - PN544_RF_READER_A_AUTO_ACTIVATION, param, 1); - if (r < 0) - return r; - - r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, - NFC_HCI_EVT_END_OPERATION, NULL, 0); - if (r < 0) - return r; - - param[0] = 0x1; - r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE, - PN544_PL_NFCT_DEACTIVATED, param, 1); - if (r < 0) - return r; - - param[0] = 0x0; - r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE, - PN544_PL_RDPHASES, param, 1); - if (r < 0) - return r; - - r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE, - PN544_ID_MGMT_FULL_VERSION_SW, &skb); - if (r < 0) - return r; - - if (skb->len != FULL_VERSION_LEN) { - kfree_skb(skb); - return -EINVAL; - } - - print_hex_dump(KERN_DEBUG, "FULL VERSION SOFTWARE INFO: ", - DUMP_PREFIX_NONE, 16, 1, - skb->data, FULL_VERSION_LEN, false); - - kfree_skb(skb); - - return 0; -} - -static int pn544_hci_xmit(struct nfc_shdlc *shdlc, struct sk_buff *skb) -{ - struct pn544_hci_info *info = nfc_shdlc_get_clientdata(shdlc); - struct i2c_client *client = info->i2c_dev; - - if (info->hard_fault != 0) - return info->hard_fault; - - return pn544_hci_i2c_write(client, skb->data, skb->len); -} - -static int pn544_hci_start_poll(struct nfc_shdlc *shdlc, u32 protocols) -{ - struct nfc_hci_dev *hdev = nfc_shdlc_get_hci_dev(shdlc); - u8 phases = 0; - int r; - u8 duration[2]; - u8 activated; - - pr_info(DRIVER_DESC ": %s protocols = %d\n", __func__, protocols); - - r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, - NFC_HCI_EVT_END_OPERATION, NULL, 0); - if (r < 0) - return r; - - duration[0] = 0x18; - duration[1] = 0x6a; - r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE, - PN544_PL_EMULATION, duration, 2); - if (r < 0) - return r; - - activated = 0; - r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE, - PN544_PL_NFCT_DEACTIVATED, &activated, 1); - if (r < 0) - return r; - - if (protocols & (NFC_PROTO_ISO14443_MASK | NFC_PROTO_MIFARE_MASK | - NFC_PROTO_JEWEL_MASK)) - phases |= 1; /* Type A */ - if (protocols & NFC_PROTO_FELICA_MASK) { - phases |= (1 << 2); /* Type F 212 */ - phases |= (1 << 3); /* Type F 424 */ - } - - phases |= (1 << 5); /* NFC active */ - - r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE, - PN544_PL_RDPHASES, &phases, 1); - if (r < 0) - return r; - - r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, - NFC_HCI_EVT_READER_REQUESTED, NULL, 0); - if (r < 0) - nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, - NFC_HCI_EVT_END_OPERATION, NULL, 0); - - return r; -} - -static int pn544_hci_target_from_gate(struct nfc_shdlc *shdlc, u8 gate, - struct nfc_target *target) -{ - switch (gate) { - case PN544_RF_READER_F_GATE: - target->supported_protocols = NFC_PROTO_FELICA_MASK; - break; - case PN544_RF_READER_JEWEL_GATE: - target->supported_protocols = NFC_PROTO_JEWEL_MASK; - target->sens_res = 0x0c00; - break; - default: - return -EPROTO; - } - - return 0; -} - -static int pn544_hci_complete_target_discovered(struct nfc_shdlc *shdlc, - u8 gate, - struct nfc_target *target) -{ - struct nfc_hci_dev *hdev = nfc_shdlc_get_hci_dev(shdlc); - struct sk_buff *uid_skb; - int r = 0; - - if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { - if (target->nfcid1_len != 4 && target->nfcid1_len != 7 && - target->nfcid1_len != 10) - return -EPROTO; - - r = nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE, - PN544_RF_READER_CMD_ACTIVATE_NEXT, - target->nfcid1, target->nfcid1_len, NULL); - } else if (target->supported_protocols & NFC_PROTO_FELICA_MASK) { - r = nfc_hci_get_param(hdev, PN544_RF_READER_F_GATE, - PN544_FELICA_ID, &uid_skb); - if (r < 0) - return r; - - if (uid_skb->len != 8) { - kfree_skb(uid_skb); - return -EPROTO; - } - - r = nfc_hci_send_cmd(hdev, PN544_RF_READER_F_GATE, - PN544_RF_READER_CMD_ACTIVATE_NEXT, - uid_skb->data, uid_skb->len, NULL); - kfree_skb(uid_skb); - } else if (target->supported_protocols & NFC_PROTO_ISO14443_MASK) { - /* - * TODO: maybe other ISO 14443 require some kind of continue - * activation, but for now we've seen only this one below. - */ - if (target->sens_res == 0x4403) /* Type 4 Mifare DESFire */ - r = nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE, - PN544_RF_READER_A_CMD_CONTINUE_ACTIVATION, - NULL, 0, NULL); - } - - return r; -} - -#define MIFARE_CMD_AUTH_KEY_A 0x60 -#define MIFARE_CMD_AUTH_KEY_B 0x61 -#define MIFARE_CMD_HEADER 2 -#define MIFARE_UID_LEN 4 -#define MIFARE_KEY_LEN 6 -#define MIFARE_CMD_LEN 12 -/* - * Returns: - * <= 0: driver handled the data exchange - * 1: driver doesn't especially handle, please do standard processing - */ -static int pn544_hci_data_exchange(struct nfc_shdlc *shdlc, - struct nfc_target *target, - struct sk_buff *skb, - struct sk_buff **res_skb) -{ - struct nfc_hci_dev *hdev = nfc_shdlc_get_hci_dev(shdlc); - int r; - - pr_info(DRIVER_DESC ": %s for gate=%d\n", __func__, - target->hci_reader_gate); - - switch (target->hci_reader_gate) { - case NFC_HCI_RF_READER_A_GATE: - if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { - /* - * It seems that pn544 is inverting key and UID for - * MIFARE authentication commands. - */ - if (skb->len == MIFARE_CMD_LEN && - (skb->data[0] == MIFARE_CMD_AUTH_KEY_A || - skb->data[0] == MIFARE_CMD_AUTH_KEY_B)) { - u8 uid[MIFARE_UID_LEN]; - u8 *data = skb->data + MIFARE_CMD_HEADER; - - memcpy(uid, data + MIFARE_KEY_LEN, - MIFARE_UID_LEN); - memmove(data + MIFARE_UID_LEN, data, - MIFARE_KEY_LEN); - memcpy(data, uid, MIFARE_UID_LEN); - } - - return nfc_hci_send_cmd(hdev, target->hci_reader_gate, - PN544_MIFARE_CMD, - skb->data, skb->len, res_skb); - } else - return 1; - case PN544_RF_READER_F_GATE: - *skb_push(skb, 1) = 0; - *skb_push(skb, 1) = 0; - - r = nfc_hci_send_cmd(hdev, target->hci_reader_gate, - PN544_FELICA_RAW, - skb->data, skb->len, res_skb); - if (r == 0) - skb_pull(*res_skb, 1); - return r; - case PN544_RF_READER_JEWEL_GATE: - return nfc_hci_send_cmd(hdev, target->hci_reader_gate, - PN544_JEWEL_RAW_CMD, - skb->data, skb->len, res_skb); - default: - return 1; - } -} - -static int pn544_hci_check_presence(struct nfc_shdlc *shdlc, - struct nfc_target *target) -{ - struct nfc_hci_dev *hdev = nfc_shdlc_get_hci_dev(shdlc); - - return nfc_hci_send_cmd(hdev, target->hci_reader_gate, - PN544_RF_READER_CMD_PRESENCE_CHECK, - NULL, 0, NULL); -} - -static struct nfc_shdlc_ops pn544_shdlc_ops = { - .open = pn544_hci_open, - .close = pn544_hci_close, - .hci_ready = pn544_hci_ready, - .xmit = pn544_hci_xmit, - .start_poll = pn544_hci_start_poll, - .target_from_gate = pn544_hci_target_from_gate, - .complete_target_discovered = pn544_hci_complete_target_discovered, - .data_exchange = pn544_hci_data_exchange, - .check_presence = pn544_hci_check_presence, -}; - -static int __devinit pn544_hci_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct pn544_hci_info *info; - struct pn544_nfc_platform_data *pdata; - int r = 0; - u32 protocols; - struct nfc_hci_init_data init_data; - - dev_dbg(&client->dev, "%s\n", __func__); - dev_dbg(&client->dev, "IRQ: %d\n", client->irq); - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "Need I2C_FUNC_I2C\n"); - return -ENODEV; - } - - info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL); - if (!info) { - dev_err(&client->dev, - "Cannot allocate memory for pn544_hci_info.\n"); - r = -ENOMEM; - goto err_info_alloc; - } - - info->i2c_dev = client; - info->state = PN544_ST_COLD; - mutex_init(&info->info_lock); - i2c_set_clientdata(client, info); - - pdata = client->dev.platform_data; - if (pdata == NULL) { - dev_err(&client->dev, "No platform data\n"); - r = -EINVAL; - goto err_pdata; - } - - if (pdata->request_resources == NULL) { - dev_err(&client->dev, "request_resources() missing\n"); - r = -EINVAL; - goto err_pdata; - } - - r = pdata->request_resources(client); - if (r) { - dev_err(&client->dev, "Cannot get platform resources\n"); - goto err_pdata; - } - - info->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); - info->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET); - info->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ); - - pn544_hci_platform_init(info); - - r = request_threaded_irq(client->irq, NULL, pn544_hci_irq_thread_fn, - IRQF_TRIGGER_RISING, PN544_HCI_DRIVER_NAME, - info); - if (r < 0) { - dev_err(&client->dev, "Unable to register IRQ handler\n"); - goto err_rti; - } - - init_data.gate_count = ARRAY_SIZE(pn544_custom_gates); - - memcpy(init_data.gates, pn544_custom_gates, - ARRAY_SIZE(pn544_custom_gates)); - - /* - * TODO: Session id must include the driver name + some bus addr - * persistent info to discriminate 2 identical chips - */ - strcpy(init_data.session_id, "ID544HCI"); - - protocols = NFC_PROTO_JEWEL_MASK | - NFC_PROTO_MIFARE_MASK | - NFC_PROTO_FELICA_MASK | - NFC_PROTO_ISO14443_MASK | - NFC_PROTO_NFC_DEP_MASK; - - info->shdlc = nfc_shdlc_allocate(&pn544_shdlc_ops, - &init_data, protocols, - PN544_CMDS_HEADROOM, 0, - PN544_HCI_LLC_MAX_PAYLOAD, - dev_name(&client->dev)); - if (!info->shdlc) { - dev_err(&client->dev, "Cannot allocate nfc shdlc.\n"); - r = -ENOMEM; - goto err_allocshdlc; - } - - nfc_shdlc_set_clientdata(info->shdlc, info); - - return 0; - -err_allocshdlc: - free_irq(client->irq, info); - -err_rti: - if (pdata->free_resources != NULL) - pdata->free_resources(); - -err_pdata: - kfree(info); - -err_info_alloc: - return r; -} - -static __devexit int pn544_hci_remove(struct i2c_client *client) -{ - struct pn544_hci_info *info = i2c_get_clientdata(client); - struct pn544_nfc_platform_data *pdata = client->dev.platform_data; - - dev_dbg(&client->dev, "%s\n", __func__); - - nfc_shdlc_free(info->shdlc); - - if (info->state != PN544_ST_COLD) { - if (pdata->disable) - pdata->disable(); - } - - free_irq(client->irq, info); - if (pdata->free_resources) - pdata->free_resources(); - - kfree(info); - - return 0; -} - -static struct i2c_driver pn544_hci_driver = { - .driver = { - .name = PN544_HCI_DRIVER_NAME, - }, - .probe = pn544_hci_probe, - .id_table = pn544_hci_id_table, - .remove = __devexit_p(pn544_hci_remove), -}; - -static int __init pn544_hci_init(void) -{ - int r; - - pr_debug(DRIVER_DESC ": %s\n", __func__); - - r = i2c_add_driver(&pn544_hci_driver); - if (r) { - pr_err(PN544_HCI_DRIVER_NAME ": driver registration failed\n"); - return r; - } - - return 0; -} - -static void __exit pn544_hci_exit(void) -{ - i2c_del_driver(&pn544_hci_driver); -} - -module_init(pn544_hci_init); -module_exit(pn544_hci_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/trunk/drivers/ssb/b43_pci_bridge.c b/trunk/drivers/ssb/b43_pci_bridge.c index f551e5376147..bad7ba517a1c 100644 --- a/trunk/drivers/ssb/b43_pci_bridge.c +++ b/trunk/drivers/ssb/b43_pci_bridge.c @@ -29,8 +29,6 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4322) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43222) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4328) }, diff --git a/trunk/drivers/ssb/pci.c b/trunk/drivers/ssb/pci.c index e9d94968f394..ed4124469a3a 100644 --- a/trunk/drivers/ssb/pci.c +++ b/trunk/drivers/ssb/pci.c @@ -178,18 +178,6 @@ int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on) #define SPEX(_outvar, _offset, _mask, _shift) \ SPEX16(_outvar, _offset, _mask, _shift) -#define SPEX_ARRAY8(_field, _offset, _mask, _shift) \ - do { \ - SPEX(_field[0], _offset + 0, _mask, _shift); \ - SPEX(_field[1], _offset + 2, _mask, _shift); \ - SPEX(_field[2], _offset + 4, _mask, _shift); \ - SPEX(_field[3], _offset + 6, _mask, _shift); \ - SPEX(_field[4], _offset + 8, _mask, _shift); \ - SPEX(_field[5], _offset + 10, _mask, _shift); \ - SPEX(_field[6], _offset + 12, _mask, _shift); \ - SPEX(_field[7], _offset + 14, _mask, _shift); \ - } while (0) - static inline u8 ssb_crc8(u8 crc, u8 data) { @@ -372,9 +360,8 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14); SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15); SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0); - if (out->revision == 1) - SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, - SSB_SPROM1_BINF_CCODE_SHIFT); + SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, + SSB_SPROM1_BINF_CCODE_SHIFT); SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA, SSB_SPROM1_BINF_ANTA_SHIFT); SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG, @@ -400,8 +387,6 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); if (out->revision >= 2) SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); - SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8); - SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0); /* Extract the antenna gain values. */ out->antenna_gain.a0 = r123_extract_antgain(out->revision, in, @@ -470,17 +455,14 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, SSB_SPROM4_ETHPHY_ET1A_SHIFT); - SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0); if (out->revision == 4) { - SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8); - SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0); + SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0); SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0); } else { - SPEX(alpha2[0], SSB_SPROM5_CCODE, 0xff00, 8); - SPEX(alpha2[1], SSB_SPROM5_CCODE, 0x00ff, 0); + SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0); SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0); SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0); SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0); @@ -543,9 +525,7 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) v = in[SPOFF(SSB_SPROM8_IL0MAC) + i]; *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); } - SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0); - SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8); - SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0); + SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0); SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0); SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0); SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0); @@ -675,63 +655,6 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); - SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON, - SSB_SPROM8_LEDDC_ON_SHIFT); - SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF, - SSB_SPROM8_LEDDC_OFF_SHIFT); - - SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN, - SSB_SPROM8_TXRXC_TXCHAIN_SHIFT); - SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN, - SSB_SPROM8_TXRXC_RXCHAIN_SHIFT); - SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH, - SSB_SPROM8_TXRXC_SWITCH_SHIFT); - - SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0); - - SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0); - SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0); - SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0); - SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0); - - SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP, - SSB_SPROM8_RAWTS_RAWTEMP_SHIFT); - SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER, - SSB_SPROM8_RAWTS_MEASPOWER_SHIFT); - SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX, - SSB_SPROM8_OPT_CORRX_TEMP_SLOPE, - SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT); - SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX, - SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT); - SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX, - SSB_SPROM8_OPT_CORRX_TEMP_OPTION, - SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT); - SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP, - SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR, - SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT); - SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP, - SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP, - SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT); - SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL, - SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT); - - SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0); - SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0); - SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0); - SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0); - - SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH, - SSB_SPROM8_THERMAL_TRESH_SHIFT); - SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET, - SSB_SPROM8_THERMAL_OFFSET_SHIFT); - SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA, - SSB_SPROM8_TEMPDELTA_PHYCAL, - SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT); - SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD, - SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT); - SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA, - SSB_SPROM8_TEMPDELTA_HYSTERESIS, - SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT); sprom_extract_r458(out, in); /* TODO - get remaining rev 8 stuff needed */ @@ -861,6 +784,7 @@ static void ssb_pci_get_boardinfo(struct ssb_bus *bus, { bi->vendor = bus->host_pci->subsystem_vendor; bi->type = bus->host_pci->subsystem_device; + bi->rev = bus->host_pci->revision; } int ssb_pci_get_invariants(struct ssb_bus *bus, diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index f08e3aec1113..3c9b616c834a 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -271,7 +271,6 @@ header-y += netfilter_ipv4.h header-y += netfilter_ipv6.h header-y += netlink.h header-y += netrom.h -header-y += nfc.h header-y += nfs.h header-y += nfs2.h header-y += nfs3.h diff --git a/trunk/include/linux/bcma/bcma.h b/trunk/include/linux/bcma/bcma.h index 747f2ca6f04e..5af9a075498f 100644 --- a/trunk/include/linux/bcma/bcma.h +++ b/trunk/include/linux/bcma/bcma.h @@ -26,11 +26,6 @@ struct bcma_chipinfo { u8 pkg; }; -struct bcma_boardinfo { - u16 vendor; - u16 type; -}; - enum bcma_clkmode { BCMA_CLKMODE_FAST, BCMA_CLKMODE_DYNAMIC, @@ -203,8 +198,6 @@ struct bcma_bus { struct bcma_chipinfo chipinfo; - struct bcma_boardinfo boardinfo; - struct bcma_device *mapped_core; struct list_head cores; u8 nr_cores; diff --git a/trunk/include/linux/bcma/bcma_driver_pci.h b/trunk/include/linux/bcma/bcma_driver_pci.h index 41da581e1612..46c71e27d31f 100644 --- a/trunk/include/linux/bcma/bcma_driver_pci.h +++ b/trunk/include/linux/bcma/bcma_driver_pci.h @@ -87,13 +87,6 @@ struct pci_dev; #define BCMA_CORE_PCI_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */ #define BCMA_CORE_PCI_PCICFG3 0x0700 /* PCI config space 3 (rev >= 8) */ #define BCMA_CORE_PCI_SPROM(wordoffset) (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */ -#define BCMA_CORE_PCI_SPROM_PI_OFFSET 0 /* first word */ -#define BCMA_CORE_PCI_SPROM_PI_MASK 0xf000 /* bit 15:12 */ -#define BCMA_CORE_PCI_SPROM_PI_SHIFT 12 /* bit 15:12 */ -#define BCMA_CORE_PCI_SPROM_MISC_CONFIG 5 /* word 5 */ -#define BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */ -#define BCMA_CORE_PCI_SPROM_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */ -#define BCMA_CORE_PCI_SPROM_CLKREQ_ENB 0x0800 /* bit 11 */ /* SBtoPCIx */ #define BCMA_CORE_PCI_SBTOPCI_MEM 0x00000000 @@ -140,7 +133,6 @@ struct pci_dev; #define BCMA_CORE_PCI_DLLP_LRREG 0x120 /* Link Replay */ #define BCMA_CORE_PCI_DLLP_LACKTOREG 0x124 /* Link Ack Timeout */ #define BCMA_CORE_PCI_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */ -#define BCMA_CORE_PCI_ASPMTIMER_EXTEND 0x01000000 /* > rev7: enable extend ASPM timer */ #define BCMA_CORE_PCI_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr */ #define BCMA_CORE_PCI_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr */ #define BCMA_CORE_PCI_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr */ @@ -209,15 +201,12 @@ struct bcma_drv_pci { }; /* Register access */ -#define pcicore_read16(pc, offset) bcma_read16((pc)->core, offset) #define pcicore_read32(pc, offset) bcma_read32((pc)->core, offset) -#define pcicore_write16(pc, offset, val) bcma_write16((pc)->core, offset, val) #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc); extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, bool enable); -extern void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend); extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev); extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev); diff --git a/trunk/include/linux/nfc/pn544.h b/trunk/include/linux/nfc/pn544.h index 9890bbaf4328..7ab8521f2347 100644 --- a/trunk/include/linux/nfc/pn544.h +++ b/trunk/include/linux/nfc/pn544.h @@ -84,12 +84,6 @@ struct pn544_fw_packet { }; #ifdef __KERNEL__ -enum { - NFC_GPIO_ENABLE, - NFC_GPIO_FW_RESET, - NFC_GPIO_IRQ -}; - /* board config */ struct pn544_nfc_platform_data { int (*request_resources) (struct i2c_client *client); @@ -97,7 +91,6 @@ struct pn544_nfc_platform_data { void (*enable) (int fw); int (*test) (void); void (*disable) (void); - int (*get_gpio)(int type); }; #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/nl80211.h b/trunk/include/linux/nl80211.h index a6959f72745e..2540e86d99ab 100644 --- a/trunk/include/linux/nl80211.h +++ b/trunk/include/linux/nl80211.h @@ -1594,8 +1594,6 @@ enum nl80211_sta_flags { NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 }; -#define NL80211_STA_FLAG_MAX_OLD_API NL80211_STA_FLAG_TDLS_PEER - /** * struct nl80211_sta_flag_update - station flags mask/set * @mask: mask of station flags to set @@ -1996,9 +1994,9 @@ enum nl80211_reg_rule_flags { * enum nl80211_dfs_regions - regulatory DFS regions * * @NL80211_DFS_UNSET: Country has no DFS master region specified - * @NL80211_DFS_FCC: Country follows DFS master rules from FCC - * @NL80211_DFS_ETSI: Country follows DFS master rules from ETSI - * @NL80211_DFS_JP: Country follows DFS master rules from JP/MKK/Telec + * @NL80211_DFS_FCC_: Country follows DFS master rules from FCC + * @NL80211_DFS_FCC_: Country follows DFS master rules from ETSI + * @NL80211_DFS_JP_: Country follows DFS master rules from JP/MKK/Telec */ enum nl80211_dfs_regions { NL80211_DFS_UNSET = 0, diff --git a/trunk/include/linux/ssb/ssb.h b/trunk/include/linux/ssb/ssb.h index bc14bd738ade..d27683180025 100644 --- a/trunk/include/linux/ssb/ssb.h +++ b/trunk/include/linux/ssb/ssb.h @@ -188,6 +188,7 @@ struct ssb_sprom { struct ssb_boardinfo { u16 vendor; u16 type; + u8 rev; }; diff --git a/trunk/include/linux/ssb/ssb_regs.h b/trunk/include/linux/ssb/ssb_regs.h index a0525019e1d1..40b1ef8595ee 100644 --- a/trunk/include/linux/ssb/ssb_regs.h +++ b/trunk/include/linux/ssb/ssb_regs.h @@ -228,7 +228,6 @@ #define SSB_SPROM1_AGAIN_BG_SHIFT 0 #define SSB_SPROM1_AGAIN_A 0xFF00 /* A-PHY */ #define SSB_SPROM1_AGAIN_A_SHIFT 8 -#define SSB_SPROM1_CCODE 0x0076 /* SPROM Revision 2 (inherits from rev 1) */ #define SSB_SPROM2_BFLHI 0x0038 /* Boardflags (high 16 bits) */ @@ -268,7 +267,6 @@ #define SSB_SPROM3_OFDMGPO 0x107A /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */ /* SPROM Revision 4 */ -#define SSB_SPROM4_BOARDREV 0x0042 /* Board revision */ #define SSB_SPROM4_BFLLO 0x0044 /* Boardflags (low 16 bits) */ #define SSB_SPROM4_BFLHI 0x0046 /* Board Flags Hi */ #define SSB_SPROM4_BFL2LO 0x0048 /* Board flags 2 (low 16 bits) */ @@ -391,11 +389,6 @@ #define SSB_SPROM8_GPIOB_P2 0x00FF /* Pin 2 */ #define SSB_SPROM8_GPIOB_P3 0xFF00 /* Pin 3 */ #define SSB_SPROM8_GPIOB_P3_SHIFT 8 -#define SSB_SPROM8_LEDDC 0x009A -#define SSB_SPROM8_LEDDC_ON 0xFF00 /* oncount */ -#define SSB_SPROM8_LEDDC_ON_SHIFT 8 -#define SSB_SPROM8_LEDDC_OFF 0x00FF /* offcount */ -#define SSB_SPROM8_LEDDC_OFF_SHIFT 0 #define SSB_SPROM8_ANTAVAIL 0x009C /* Antenna available bitfields*/ #define SSB_SPROM8_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */ #define SSB_SPROM8_ANTAVAIL_A_SHIFT 8 @@ -411,13 +404,6 @@ #define SSB_SPROM8_AGAIN2_SHIFT 0 #define SSB_SPROM8_AGAIN3 0xFF00 /* Antenna 3 */ #define SSB_SPROM8_AGAIN3_SHIFT 8 -#define SSB_SPROM8_TXRXC 0x00A2 -#define SSB_SPROM8_TXRXC_TXCHAIN 0x000f -#define SSB_SPROM8_TXRXC_TXCHAIN_SHIFT 0 -#define SSB_SPROM8_TXRXC_RXCHAIN 0x00f0 -#define SSB_SPROM8_TXRXC_RXCHAIN_SHIFT 4 -#define SSB_SPROM8_TXRXC_SWITCH 0xff00 -#define SSB_SPROM8_TXRXC_SWITCH_SHIFT 8 #define SSB_SPROM8_RSSIPARM2G 0x00A4 /* RSSI params for 2GHz */ #define SSB_SPROM8_RSSISMF2G 0x000F #define SSB_SPROM8_RSSISMC2G 0x00F0 @@ -444,7 +430,6 @@ #define SSB_SPROM8_TRI5GH_SHIFT 8 #define SSB_SPROM8_RXPO 0x00AC /* RX power offsets */ #define SSB_SPROM8_RXPO2G 0x00FF /* 2GHz RX power offset */ -#define SSB_SPROM8_RXPO2G_SHIFT 0 #define SSB_SPROM8_RXPO5G 0xFF00 /* 5GHz RX power offset */ #define SSB_SPROM8_RXPO5G_SHIFT 8 #define SSB_SPROM8_FEM2G 0x00AE @@ -460,38 +445,10 @@ #define SSB_SROM8_FEM_ANTSWLUT 0xF800 #define SSB_SROM8_FEM_ANTSWLUT_SHIFT 11 #define SSB_SPROM8_THERMAL 0x00B2 -#define SSB_SPROM8_THERMAL_OFFSET 0x00ff -#define SSB_SPROM8_THERMAL_OFFSET_SHIFT 0 -#define SSB_SPROM8_THERMAL_TRESH 0xff00 -#define SSB_SPROM8_THERMAL_TRESH_SHIFT 8 -/* Temp sense related entries */ -#define SSB_SPROM8_RAWTS 0x00B4 -#define SSB_SPROM8_RAWTS_RAWTEMP 0x01ff -#define SSB_SPROM8_RAWTS_RAWTEMP_SHIFT 0 -#define SSB_SPROM8_RAWTS_MEASPOWER 0xfe00 -#define SSB_SPROM8_RAWTS_MEASPOWER_SHIFT 9 -#define SSB_SPROM8_OPT_CORRX 0x00B6 -#define SSB_SPROM8_OPT_CORRX_TEMP_SLOPE 0x00ff -#define SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT 0 -#define SSB_SPROM8_OPT_CORRX_TEMPCORRX 0xfc00 -#define SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT 10 -#define SSB_SPROM8_OPT_CORRX_TEMP_OPTION 0x0300 -#define SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT 8 -/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */ -#define SSB_SPROM8_HWIQ_IQSWP 0x00B8 -#define SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR 0x000f -#define SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT 0 -#define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP 0x0010 -#define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT 4 -#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL 0x0020 -#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT 5 -#define SSB_SPROM8_TEMPDELTA 0x00BA -#define SSB_SPROM8_TEMPDELTA_PHYCAL 0x00ff -#define SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT 0 -#define SSB_SPROM8_TEMPDELTA_PERIOD 0x0f00 -#define SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT 8 -#define SSB_SPROM8_TEMPDELTA_HYSTERESIS 0xf000 -#define SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT 12 +#define SSB_SPROM8_MPWR_RAWTS 0x00B4 +#define SSB_SPROM8_TS_SLP_OPT_CORRX 0x00B6 +#define SSB_SPROM8_FOC_HWIQ_IQSWP 0x00B8 +#define SSB_SPROM8_PHYCAL_TEMPDELTA 0x00BA /* There are 4 blocks with power info sharing the same layout */ #define SSB_SROM8_PWR_INFO_CORE0 0x00C0 @@ -556,16 +513,6 @@ #define SSB_SPROM8_OFDM5GLPO 0x014A /* 5.2GHz OFDM power offset */ #define SSB_SPROM8_OFDM5GHPO 0x014E /* 5.8GHz OFDM power offset */ -#define SSB_SPROM8_2G_MCSPO 0x0152 -#define SSB_SPROM8_5G_MCSPO 0x0162 -#define SSB_SPROM8_5GL_MCSPO 0x0172 -#define SSB_SPROM8_5GH_MCSPO 0x0182 - -#define SSB_SPROM8_CDDPO 0x0192 -#define SSB_SPROM8_STBCPO 0x0194 -#define SSB_SPROM8_BW40PO 0x0196 -#define SSB_SPROM8_BWDUPPO 0x0198 - /* Values for boardflags_lo read from SPROM */ #define SSB_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */ #define SSB_BFL_PACTRL 0x0002 /* GPIO 9 controlling the PA */ diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index 0289d4ce7070..adb2320bccdf 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -3365,9 +3365,9 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, * @chan: main channel * @channel_type: HT mode */ -bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type); +int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type); /* * cfg80211_ch_switch_notify - update wdev channel and notify userspace diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index 1937c7d98304..4d6e6c6818d0 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -667,9 +667,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * @RX_FLAG_SHORT_GI: Short guard interval was used * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present. * Valid only for data frames (mainly A-MPDU) - * @RX_FLAG_HT_GF: This frame was received in a HT-greenfield transmission, if - * the driver fills this value it should add %IEEE80211_RADIOTAP_MCS_HAVE_FMT - * to hw.radiotap_mcs_details to advertise that fact */ enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR = 1<<0, @@ -684,7 +681,6 @@ enum mac80211_rx_flags { RX_FLAG_40MHZ = 1<<10, RX_FLAG_SHORT_GI = 1<<11, RX_FLAG_NO_SIGNAL_VAL = 1<<12, - RX_FLAG_HT_GF = 1<<13, }; /** @@ -943,7 +939,7 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif) * CCMP key if it requires CCMP encryption of management frames (MFP) to * be done in software. * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver - * if space should be prepared for the IV, but the IV + * for a CCMP key if space should be prepared for the IV, but the IV * itself should not be generated. Do not set together with * @IEEE80211_KEY_FLAG_GENERATE_IV on the same key. */ @@ -1292,11 +1288,6 @@ enum ieee80211_hw_flags { * * @offchannel_tx_hw_queue: HW queue ID to use for offchannel TX * (if %IEEE80211_HW_QUEUE_CONTROL is set) - * - * @radiotap_mcs_details: lists which MCS information can the HW - * reports, by default it is set to _MCS, _GI and _BW but doesn't - * include _FMT. Use %IEEE80211_RADIOTAP_MCS_HAVE_* values, only - * adding _BW is supported today. */ struct ieee80211_hw { struct ieee80211_conf conf; @@ -1318,7 +1309,6 @@ struct ieee80211_hw { u8 max_rx_aggregation_subframes; u8 max_tx_aggregation_subframes; u8 offchannel_tx_hw_queue; - u8 radiotap_mcs_details; }; /** diff --git a/trunk/include/net/nfc/hci.h b/trunk/include/net/nfc/hci.h index 4467c9460857..aca65a5a9d0d 100644 --- a/trunk/include/net/nfc/hci.h +++ b/trunk/include/net/nfc/hci.h @@ -39,8 +39,6 @@ struct nfc_hci_ops { int (*data_exchange) (struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, struct sk_buff **res_skb); - int (*check_presence)(struct nfc_hci_dev *hdev, - struct nfc_target *target); }; #define NFC_HCI_MAX_CUSTOM_GATES 15 @@ -84,6 +82,10 @@ struct nfc_hci_dev { u8 gate2pipe[NFC_HCI_MAX_GATES]; + bool poll_started; + struct nfc_target *targets; + int target_count; + u8 sw_romlib; u8 sw_patch; u8 sw_flashlib_major; diff --git a/trunk/include/net/nfc/nfc.h b/trunk/include/net/nfc/nfc.h index b7ca4a2a1d72..9a2505a5b8de 100644 --- a/trunk/include/net/nfc/nfc.h +++ b/trunk/include/net/nfc/nfc.h @@ -48,28 +48,26 @@ struct nfc_dev; typedef void (*data_exchange_cb_t)(void *context, struct sk_buff *skb, int err); -struct nfc_target; - struct nfc_ops { int (*dev_up)(struct nfc_dev *dev); int (*dev_down)(struct nfc_dev *dev); int (*start_poll)(struct nfc_dev *dev, u32 protocols); void (*stop_poll)(struct nfc_dev *dev); - int (*dep_link_up)(struct nfc_dev *dev, struct nfc_target *target, - u8 comm_mode, u8 *gb, size_t gb_len); + int (*dep_link_up)(struct nfc_dev *dev, int target_idx, u8 comm_mode, + u8 *gb, size_t gb_len); int (*dep_link_down)(struct nfc_dev *dev); - int (*activate_target)(struct nfc_dev *dev, struct nfc_target *target, + int (*activate_target)(struct nfc_dev *dev, u32 target_idx, u32 protocol); - void (*deactivate_target)(struct nfc_dev *dev, - struct nfc_target *target); - int (*data_exchange)(struct nfc_dev *dev, struct nfc_target *target, + void (*deactivate_target)(struct nfc_dev *dev, u32 target_idx); + int (*data_exchange)(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context); - int (*check_presence)(struct nfc_dev *dev, struct nfc_target *target); + int (*check_presence)(struct nfc_dev *dev, u32 target_idx); }; #define NFC_TARGET_IDX_ANY -1 #define NFC_MAX_GT_LEN 48 +#define NFC_TARGET_IDX_NONE 0xffffffff struct nfc_target { u32 idx; @@ -97,10 +95,11 @@ struct nfc_dev { struct nfc_target *targets; int n_targets; int targets_generation; + spinlock_t targets_lock; struct device dev; bool dev_up; bool polling; - struct nfc_target *active_target; + u32 activated_target_idx; bool dep_link_up; u32 dep_rf_mode; struct nfc_genl_data genl_data; diff --git a/trunk/include/net/nfc/shdlc.h b/trunk/include/net/nfc/shdlc.h index ab06afd462da..1071987d0408 100644 --- a/trunk/include/net/nfc/shdlc.h +++ b/trunk/include/net/nfc/shdlc.h @@ -35,8 +35,6 @@ struct nfc_shdlc_ops { int (*data_exchange) (struct nfc_shdlc *shdlc, struct nfc_target *target, struct sk_buff *skb, struct sk_buff **res_skb); - int (*check_presence)(struct nfc_shdlc *shdlc, - struct nfc_target *target); }; enum shdlc_state { diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index 6c065254afc0..982ae3c52db4 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -3336,7 +3336,7 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, struct hci_conn *conn; struct smp_ltk *ltk; - BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle)); + BT_DBG("%s handle %d", hdev->name, __le16_to_cpu(ev->handle)); hci_dev_lock(hdev); diff --git a/trunk/net/mac80211/agg-tx.c b/trunk/net/mac80211/agg-tx.c index 7cf07158805c..5b7053c58732 100644 --- a/trunk/net/mac80211/agg-tx.c +++ b/trunk/net/mac80211/agg-tx.c @@ -421,22 +421,16 @@ static void sta_tx_agg_session_timer_expired(unsigned long data) struct tid_ampdu_tx *tid_tx; unsigned long timeout; - rcu_read_lock(); - tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[*ptid]); - if (!tid_tx || test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { - rcu_read_unlock(); + tid_tx = rcu_dereference_protected_tid_tx(sta, *ptid); + if (!tid_tx) return; - } timeout = tid_tx->last_tx + TU_TO_JIFFIES(tid_tx->timeout); if (time_is_after_jiffies(timeout)) { mod_timer(&tid_tx->session_timer, timeout); - rcu_read_unlock(); return; } - rcu_read_unlock(); - #ifdef CONFIG_MAC80211_HT_DEBUG printk(KERN_DEBUG "tx session timer expired on tid %d\n", (u16)*ptid); #endif diff --git a/trunk/net/mac80211/debugfs_netdev.c b/trunk/net/mac80211/debugfs_netdev.c index 7ed433c66d68..ea0122dbd2b3 100644 --- a/trunk/net/mac80211/debugfs_netdev.c +++ b/trunk/net/mac80211/debugfs_netdev.c @@ -509,7 +509,6 @@ IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); -IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC); #endif #define DEBUGFS_ADD_MODE(name, mode) \ @@ -609,7 +608,6 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) MESHPARAMS_ADD(dot11MeshHWMPRannInterval); MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); MESHPARAMS_ADD(rssi_threshold); - MESHPARAMS_ADD(ht_opmode); #undef MESHPARAMS_ADD } #endif diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index 11ac1ffd9570..bb1a3e62a66a 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -163,11 +163,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, sizeof(struct ieee80211_ht_operation)); pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, sband->ht_cap.cap); - /* - * Note: According to 802.11n-2009 9.13.3.1, HT Protection - * field and RIFS Mode are reserved in IBSS mode, therefore - * keep them at 0 - */ pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, chan, channel_type, 0); } diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index c550945dd703..3e05a8bfddf0 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -206,10 +206,8 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) for (i = 0; i < IEEE80211_NUM_ACS; i++) { if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) sdata->vif.hw_queue[i] = IEEE80211_INVAL_HW_QUEUE; - else if (local->hw.queues >= IEEE80211_NUM_ACS) - sdata->vif.hw_queue[i] = i; else - sdata->vif.hw_queue[i] = 0; + sdata->vif.hw_queue[i] = i; } sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; } diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index f5548e953259..b70f7f09da61 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -596,9 +596,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, local->hw.offchannel_tx_hw_queue = IEEE80211_INVAL_HW_QUEUE; local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; - local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS | - IEEE80211_RADIOTAP_MCS_HAVE_GI | - IEEE80211_RADIOTAP_MCS_HAVE_BW; local->user_power_level = -1; wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; diff --git a/trunk/net/mac80211/mesh.c b/trunk/net/mac80211/mesh.c index d3a9a6c081e7..0a21e4e55f43 100644 --- a/trunk/net/mac80211/mesh.c +++ b/trunk/net/mac80211/mesh.c @@ -109,10 +109,8 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, /* Disallow HT40+/- mismatch */ if (ie->ht_operation && - (local->_oper_channel_type == NL80211_CHAN_HT40MINUS || - local->_oper_channel_type == NL80211_CHAN_HT40PLUS) && - (sta_channel_type == NL80211_CHAN_HT40MINUS || - sta_channel_type == NL80211_CHAN_HT40PLUS) && + local->_oper_channel_type > NL80211_CHAN_HT20 && + sta_channel_type > NL80211_CHAN_HT20 && local->_oper_channel_type != sta_channel_type) goto mismatch; diff --git a/trunk/net/mac80211/mesh_hwmp.c b/trunk/net/mac80211/mesh_hwmp.c index 70ac7d180077..503016f58631 100644 --- a/trunk/net/mac80211/mesh_hwmp.c +++ b/trunk/net/mac80211/mesh_hwmp.c @@ -603,10 +603,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, hopcount, ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), cpu_to_le32(preq_id), sdata); - if (!is_multicast_ether_addr(da)) - ifmsh->mshstats.fwded_unicast++; - else - ifmsh->mshstats.fwded_mcast++; + ifmsh->mshstats.fwded_mcast++; ifmsh->mshstats.fwded_frames++; } } diff --git a/trunk/net/mac80211/mesh_plink.c b/trunk/net/mac80211/mesh_plink.c index 60ef235c9d9b..8cc8461b48a0 100644 --- a/trunk/net/mac80211/mesh_plink.c +++ b/trunk/net/mac80211/mesh_plink.c @@ -105,15 +105,15 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, return sta; } -/* - * mesh_set_ht_prot_mode - set correct HT protection mode +/** mesh_set_ht_prot_mode - set correct HT protection mode * - * Section 9.23.3.5 of IEEE 80211-2012 describes the protection rules for HT - * mesh STA in a MBSS. Three HT protection modes are supported for now, non-HT - * mixed mode, 20MHz-protection and no-protection mode. non-HT mixed mode is - * selected if any non-HT peers are present in our MBSS. 20MHz-protection mode - * is selected if all peers in our 20/40MHz MBSS support HT and atleast one - * HT20 peer is present. Otherwise no-protection mode is selected. + * Section 9.23.3.5 of IEEE 80211s standard describes the protection rules for + * HT mesh STA in a MBSS. Three HT protection modes are supported for now, + * non-HT mixed mode, 20MHz-protection and no-protection mode. non-HT mixed + * mode is selected if any non-HT peers are present in our MBSS. + * 20MHz-protection mode is selected if all peers in our 20/40MHz MBSS support + * HT and atleast one HT20 peer is present. Otherwise no-protection mode is + * selected. */ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) { @@ -128,22 +128,21 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) rcu_read_lock(); list_for_each_entry_rcu(sta, &local->sta_list, list) { - if (sdata != sta->sdata || - sta->plink_state != NL80211_PLINK_ESTAB) - continue; - - switch (sta->ch_type) { - case NL80211_CHAN_NO_HT: - mpl_dbg("mesh_plink %pM: nonHT sta (%pM) is present", - sdata->vif.addr, sta->sta.addr); - non_ht_sta = true; - goto out; - case NL80211_CHAN_HT20: - mpl_dbg("mesh_plink %pM: HT20 sta (%pM) is present", - sdata->vif.addr, sta->sta.addr); - ht20_sta = true; - default: - break; + if (sdata == sta->sdata && + sta->plink_state == NL80211_PLINK_ESTAB) { + switch (sta->ch_type) { + case NL80211_CHAN_NO_HT: + mpl_dbg("mesh_plink %pM: nonHT sta (%pM) is present", + sdata->vif.addr, sta->sta.addr); + non_ht_sta = true; + goto out; + case NL80211_CHAN_HT20: + mpl_dbg("mesh_plink %pM: HT20 sta (%pM) is present", + sdata->vif.addr, sta->sta.addr); + ht20_sta = true; + default: + break; + } } } out: @@ -347,15 +346,6 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata, sta = sta_info_get(sdata, addr); if (!sta) { - /* Userspace handles peer allocation when security is enabled */ - if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) { - cfg80211_notify_new_peer_candidate(sdata->dev, addr, - elems->ie_start, - elems->total_len, - GFP_ATOMIC); - return NULL; - } - sta = mesh_plink_alloc(sdata, addr); if (!sta) return NULL; @@ -397,6 +387,15 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, { struct sta_info *sta; + /* Userspace handles peer allocation when security is enabled */ + if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) { + cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, + elems->ie_start, + elems->total_len, + GFP_KERNEL); + return; + } + rcu_read_lock(); sta = mesh_peer_init(sdata, hw_addr, elems); if (!sta) diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index 489093b08a4a..d5ac02fe37ff 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -204,14 +204,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, if (status->flag & RX_FLAG_HT) { rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS); - *pos++ = local->hw.radiotap_mcs_details; + *pos++ = IEEE80211_RADIOTAP_MCS_HAVE_MCS | + IEEE80211_RADIOTAP_MCS_HAVE_GI | + IEEE80211_RADIOTAP_MCS_HAVE_BW; *pos = 0; if (status->flag & RX_FLAG_SHORT_GI) *pos |= IEEE80211_RADIOTAP_MCS_SGI; if (status->flag & RX_FLAG_40MHZ) *pos |= IEEE80211_RADIOTAP_MCS_BW_40; - if (status->flag & RX_FLAG_HT_GF) - *pos |= IEEE80211_RADIOTAP_MCS_FMT_GF; pos++; *pos++ = status->rate_idx; } diff --git a/trunk/net/mac80211/wep.c b/trunk/net/mac80211/wep.c index c04d401dae92..7aa31bbfaa3b 100644 --- a/trunk/net/mac80211/wep.c +++ b/trunk/net/mac80211/wep.c @@ -92,7 +92,6 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, int keylen, int keyidx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); unsigned int hdrlen; u8 *newhdr; @@ -105,13 +104,6 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, hdrlen = ieee80211_hdrlen(hdr->frame_control); newhdr = skb_push(skb, WEP_IV_LEN); memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); - - /* the HW only needs room for the IV, but not the actual IV */ - if (info->control.hw_key && - (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) - return newhdr + hdrlen; - - skb_set_network_header(skb, skb_network_offset(skb) + WEP_IV_LEN); ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); return newhdr + hdrlen; } @@ -321,15 +313,14 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_key_conf *hw_key = info->control.hw_key; - if (!hw_key) { + if (!info->control.hw_key) { if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key, tx->key->conf.keylen, tx->key->conf.keyidx)) return -1; - } else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) || - (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { + } else if (info->control.hw_key->flags & + IEEE80211_KEY_FLAG_GENERATE_IV) { if (!ieee80211_wep_add_iv(tx->local, skb, tx->key->conf.keylen, tx->key->conf.keyidx)) diff --git a/trunk/net/mac80211/wpa.c b/trunk/net/mac80211/wpa.c index bdb53aba888e..0ae23c60968c 100644 --- a/trunk/net/mac80211/wpa.c +++ b/trunk/net/mac80211/wpa.c @@ -183,8 +183,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) u8 *pos; if (info->control.hw_key && - !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) && - !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { + !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { /* hwaccel - with no need for software-generated IV */ return 0; } @@ -203,14 +202,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) pos = skb_push(skb, TKIP_IV_LEN); memmove(pos, pos + TKIP_IV_LEN, hdrlen); - skb_set_network_header(skb, skb_network_offset(skb) + TKIP_IV_LEN); pos += hdrlen; - /* the HW only needs room for the IV, but not the actual IV */ - if (info->control.hw_key && - (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) - return 0; - /* Increase IV for the frame */ spin_lock_irqsave(&key->u.tkip.txlock, flags); key->u.tkip.tx.iv16++; @@ -429,7 +422,6 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) pos = skb_push(skb, CCMP_HDR_LEN); memmove(pos, pos + CCMP_HDR_LEN, hdrlen); - skb_set_network_header(skb, skb_network_offset(skb) + CCMP_HDR_LEN); /* the HW only needs room for the IV, but not the actual IV */ if (info->control.hw_key && diff --git a/trunk/net/nfc/core.c b/trunk/net/nfc/core.c index 9f6ce011d35d..3192c3f589ee 100644 --- a/trunk/net/nfc/core.c +++ b/trunk/net/nfc/core.c @@ -97,7 +97,7 @@ int nfc_dev_down(struct nfc_dev *dev) goto error; } - if (dev->polling || dev->active_target) { + if (dev->polling || dev->activated_target_idx != NFC_TARGET_IDX_NONE) { rc = -EBUSY; goto error; } @@ -183,27 +183,11 @@ int nfc_stop_poll(struct nfc_dev *dev) return rc; } -static struct nfc_target *nfc_find_target(struct nfc_dev *dev, u32 target_idx) -{ - int i; - - if (dev->n_targets == 0) - return NULL; - - for (i = 0; i < dev->n_targets ; i++) { - if (dev->targets[i].idx == target_idx) - return &dev->targets[i]; - } - - return NULL; -} - int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode) { int rc = 0; u8 *gb; size_t gb_len; - struct nfc_target *target; pr_debug("dev_name=%s comm %d\n", dev_name(&dev->dev), comm_mode); @@ -228,15 +212,9 @@ int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode) goto error; } - target = nfc_find_target(dev, target_index); - if (target == NULL) { - rc = -ENOTCONN; - goto error; - } - - rc = dev->ops->dep_link_up(dev, target, comm_mode, gb, gb_len); + rc = dev->ops->dep_link_up(dev, target_index, comm_mode, gb, gb_len); if (!rc) - dev->active_target = target; + dev->activated_target_idx = target_index; error: device_unlock(&dev->dev); @@ -272,7 +250,7 @@ int nfc_dep_link_down(struct nfc_dev *dev) rc = dev->ops->dep_link_down(dev); if (!rc) { dev->dep_link_up = false; - dev->active_target = NULL; + dev->activated_target_idx = NFC_TARGET_IDX_NONE; nfc_llcp_mac_is_down(dev); nfc_genl_dep_link_down_event(dev); } @@ -304,7 +282,6 @@ EXPORT_SYMBOL(nfc_dep_link_is_up); int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol) { int rc; - struct nfc_target *target; pr_debug("dev_name=%s target_idx=%u protocol=%u\n", dev_name(&dev->dev), target_idx, protocol); @@ -316,20 +293,9 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol) goto error; } - if (dev->active_target) { - rc = -EBUSY; - goto error; - } - - target = nfc_find_target(dev, target_idx); - if (target == NULL) { - rc = -ENOTCONN; - goto error; - } - - rc = dev->ops->activate_target(dev, target, protocol); + rc = dev->ops->activate_target(dev, target_idx, protocol); if (!rc) { - dev->active_target = target; + dev->activated_target_idx = target_idx; if (dev->ops->check_presence) mod_timer(&dev->check_pres_timer, jiffies + @@ -361,21 +327,11 @@ int nfc_deactivate_target(struct nfc_dev *dev, u32 target_idx) goto error; } - if (dev->active_target == NULL) { - rc = -ENOTCONN; - goto error; - } - - if (dev->active_target->idx != target_idx) { - rc = -ENOTCONN; - goto error; - } - if (dev->ops->check_presence) del_timer_sync(&dev->check_pres_timer); - dev->ops->deactivate_target(dev, dev->active_target); - dev->active_target = NULL; + dev->ops->deactivate_target(dev, target_idx); + dev->activated_target_idx = NFC_TARGET_IDX_NONE; error: device_unlock(&dev->dev); @@ -409,13 +365,13 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, goto error; } - if (dev->active_target == NULL) { + if (dev->activated_target_idx == NFC_TARGET_IDX_NONE) { rc = -ENOTCONN; kfree_skb(skb); goto error; } - if (dev->active_target->idx != target_idx) { + if (target_idx != dev->activated_target_idx) { rc = -EADDRNOTAVAIL; kfree_skb(skb); goto error; @@ -424,8 +380,7 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, if (dev->ops->check_presence) del_timer_sync(&dev->check_pres_timer); - rc = dev->ops->data_exchange(dev, dev->active_target, skb, cb, - cb_context); + rc = dev->ops->data_exchange(dev, target_idx, skb, cb, cb_context); if (!rc && dev->ops->check_presence) mod_timer(&dev->check_pres_timer, jiffies + @@ -501,9 +456,6 @@ EXPORT_SYMBOL(nfc_alloc_recv_skb); * The device driver must call this function when one or many nfc targets * are found. After calling this function, the device driver must stop * polling for targets. - * IMPORTANT: this function must not be called from an atomic context. - * In addition, it must also not be called from a context that would prevent - * the NFC Core to call other nfc ops entry point concurrently. */ int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, int n_targets) @@ -517,7 +469,7 @@ int nfc_targets_found(struct nfc_dev *dev, for (i = 0; i < n_targets; i++) targets[i].idx = dev->target_next_idx++; - device_lock(&dev->dev); + spin_lock_bh(&dev->targets_lock); dev->targets_generation++; @@ -527,12 +479,12 @@ int nfc_targets_found(struct nfc_dev *dev, if (!dev->targets) { dev->n_targets = 0; - device_unlock(&dev->dev); + spin_unlock_bh(&dev->targets_lock); return -ENOMEM; } dev->n_targets = n_targets; - device_unlock(&dev->dev); + spin_unlock_bh(&dev->targets_lock); nfc_genl_targets_found(dev); @@ -540,18 +492,6 @@ int nfc_targets_found(struct nfc_dev *dev, } EXPORT_SYMBOL(nfc_targets_found); -/** - * nfc_target_lost - inform that an activated target went out of field - * - * @dev: The nfc device that had the activated target in field - * @target_idx: the nfc index of the target - * - * The device driver must call this function when the activated target - * goes out of the field. - * IMPORTANT: this function must not be called from an atomic context. - * In addition, it must also not be called from a context that would prevent - * the NFC Core to call other nfc ops entry point concurrently. - */ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx) { struct nfc_target *tg; @@ -559,7 +499,7 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx) pr_debug("dev_name %s n_target %d\n", dev_name(&dev->dev), target_idx); - device_lock(&dev->dev); + spin_lock_bh(&dev->targets_lock); for (i = 0; i < dev->n_targets; i++) { tg = &dev->targets[i]; @@ -568,13 +508,13 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx) } if (i == dev->n_targets) { - device_unlock(&dev->dev); + spin_unlock_bh(&dev->targets_lock); return -EINVAL; } dev->targets_generation++; dev->n_targets--; - dev->active_target = NULL; + dev->activated_target_idx = NFC_TARGET_IDX_NONE; if (dev->n_targets) { memcpy(&dev->targets[i], &dev->targets[i + 1], @@ -584,7 +524,7 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx) dev->targets = NULL; } - device_unlock(&dev->dev); + spin_unlock_bh(&dev->targets_lock); nfc_genl_target_lost(dev, target_idx); @@ -616,16 +556,15 @@ static void nfc_check_pres_work(struct work_struct *work) device_lock(&dev->dev); - if (dev->active_target && timer_pending(&dev->check_pres_timer) == 0) { - rc = dev->ops->check_presence(dev, dev->active_target); + if (dev->activated_target_idx != NFC_TARGET_IDX_NONE && + timer_pending(&dev->check_pres_timer) == 0) { + rc = dev->ops->check_presence(dev, dev->activated_target_idx); if (!rc) { mod_timer(&dev->check_pres_timer, jiffies + msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); } else { - u32 active_target_idx = dev->active_target->idx; - device_unlock(&dev->dev); - nfc_target_lost(dev, active_target_idx); - return; + nfc_target_lost(dev, dev->activated_target_idx); + dev->activated_target_idx = NFC_TARGET_IDX_NONE; } } @@ -698,12 +637,14 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, dev->tx_headroom = tx_headroom; dev->tx_tailroom = tx_tailroom; + spin_lock_init(&dev->targets_lock); nfc_genl_data_init(&dev->genl_data); - /* first generation must not be 0 */ dev->targets_generation = 1; + dev->activated_target_idx = NFC_TARGET_IDX_NONE; + if (ops->check_presence) { char name[32]; init_timer(&dev->check_pres_timer); @@ -721,6 +662,7 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, } } + return dev; } EXPORT_SYMBOL(nfc_allocate_device); diff --git a/trunk/net/nfc/hci/Kconfig b/trunk/net/nfc/hci/Kconfig index fd67f51d18e9..17213a6362b4 100644 --- a/trunk/net/nfc/hci/Kconfig +++ b/trunk/net/nfc/hci/Kconfig @@ -9,7 +9,6 @@ config NFC_HCI config NFC_SHDLC depends on NFC_HCI - select CRC_CCITT bool "SHDLC link layer for HCI based NFC drivers" default n ---help--- diff --git a/trunk/net/nfc/hci/core.c b/trunk/net/nfc/hci/core.c index e1a640d2b588..86fd00d5a099 100644 --- a/trunk/net/nfc/hci/core.c +++ b/trunk/net/nfc/hci/core.c @@ -235,6 +235,13 @@ static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) targets->hci_reader_gate = gate; r = nfc_targets_found(hdev->ndev, targets, 1); + if (r < 0) + goto exit; + + kfree(hdev->targets); + hdev->targets = targets; + targets = NULL; + hdev->target_count = 1; exit: kfree(targets); @@ -251,6 +258,11 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, switch (event) { case NFC_HCI_EVT_TARGET_DISCOVERED: + if (hdev->poll_started == false) { + r = -EPROTO; + goto exit; + } + if (skb->len < 1) { /* no status data? */ r = -EPROTO; goto exit; @@ -484,42 +496,74 @@ static int hci_dev_down(struct nfc_dev *nfc_dev) static int hci_start_poll(struct nfc_dev *nfc_dev, u32 protocols) { struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); + int r; if (hdev->ops->start_poll) - return hdev->ops->start_poll(hdev, protocols); + r = hdev->ops->start_poll(hdev, protocols); else - return nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, + r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, NFC_HCI_EVT_READER_REQUESTED, NULL, 0); + if (r == 0) + hdev->poll_started = true; + + return r; } static void hci_stop_poll(struct nfc_dev *nfc_dev) { struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); - nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, - NFC_HCI_EVT_END_OPERATION, NULL, 0); + if (hdev->poll_started) { + nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, + NFC_HCI_EVT_END_OPERATION, NULL, 0); + hdev->poll_started = false; + } +} + +static struct nfc_target *hci_find_target(struct nfc_hci_dev *hdev, + u32 target_idx) +{ + int i; + if (hdev->poll_started == false || hdev->targets == NULL) + return NULL; + + for (i = 0; i < hdev->target_count; i++) { + if (hdev->targets[i].idx == target_idx) + return &hdev->targets[i]; + } + + return NULL; } -static int hci_activate_target(struct nfc_dev *nfc_dev, - struct nfc_target *target, u32 protocol) +static int hci_activate_target(struct nfc_dev *nfc_dev, u32 target_idx, + u32 protocol) { + struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); + + if (hci_find_target(hdev, target_idx) == NULL) + return -ENOMEDIUM; + return 0; } -static void hci_deactivate_target(struct nfc_dev *nfc_dev, - struct nfc_target *target) +static void hci_deactivate_target(struct nfc_dev *nfc_dev, u32 target_idx) { } -static int hci_data_exchange(struct nfc_dev *nfc_dev, struct nfc_target *target, +static int hci_data_exchange(struct nfc_dev *nfc_dev, u32 target_idx, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) { struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); int r; + struct nfc_target *target; struct sk_buff *res_skb = NULL; - pr_debug("target_idx=%d\n", target->idx); + pr_debug("target_idx=%d\n", target_idx); + + target = hci_find_target(hdev, target_idx); + if (target == NULL) + return -ENOMEDIUM; switch (target->hci_reader_gate) { case NFC_HCI_RF_READER_A_GATE: @@ -561,18 +605,7 @@ static int hci_data_exchange(struct nfc_dev *nfc_dev, struct nfc_target *target, return 0; } -static int hci_check_presence(struct nfc_dev *nfc_dev, - struct nfc_target *target) -{ - struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); - - if (hdev->ops->check_presence) - return hdev->ops->check_presence(hdev, target); - - return 0; -} - -static struct nfc_ops hci_nfc_ops = { +struct nfc_ops hci_nfc_ops = { .dev_up = hci_dev_up, .dev_down = hci_dev_down, .start_poll = hci_start_poll, @@ -580,7 +613,6 @@ static struct nfc_ops hci_nfc_ops = { .activate_target = hci_activate_target, .deactivate_target = hci_deactivate_target, .data_exchange = hci_data_exchange, - .check_presence = hci_check_presence, }; struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops, diff --git a/trunk/net/nfc/hci/shdlc.c b/trunk/net/nfc/hci/shdlc.c index 5665dc6d893a..923bdf7c26d6 100644 --- a/trunk/net/nfc/hci/shdlc.c +++ b/trunk/net/nfc/hci/shdlc.c @@ -816,17 +816,6 @@ static int nfc_shdlc_data_exchange(struct nfc_hci_dev *hdev, return -EPERM; } -static int nfc_shdlc_check_presence(struct nfc_hci_dev *hdev, - struct nfc_target *target) -{ - struct nfc_shdlc *shdlc = nfc_hci_get_clientdata(hdev); - - if (shdlc->ops->check_presence) - return shdlc->ops->check_presence(shdlc, target); - - return 0; -} - static struct nfc_hci_ops shdlc_ops = { .open = nfc_shdlc_open, .close = nfc_shdlc_close, @@ -836,7 +825,6 @@ static struct nfc_hci_ops shdlc_ops = { .target_from_gate = nfc_shdlc_target_from_gate, .complete_target_discovered = nfc_shdlc_complete_target_discovered, .data_exchange = nfc_shdlc_data_exchange, - .check_presence = nfc_shdlc_check_presence, }; struct nfc_shdlc *nfc_shdlc_allocate(struct nfc_shdlc_ops *ops, diff --git a/trunk/net/nfc/llcp/commands.c b/trunk/net/nfc/llcp/commands.c index bf8ae4f0b90c..11a3b7d98dc5 100644 --- a/trunk/net/nfc/llcp/commands.c +++ b/trunk/net/nfc/llcp/commands.c @@ -488,7 +488,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); - skb_queue_tail(&sock->tx_queue, pdu); + skb_queue_head(&sock->tx_queue, pdu); lock_sock(sk); @@ -502,7 +502,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, kfree(msg_data); - return len; + return 0; } int nfc_llcp_send_rr(struct nfc_llcp_sock *sock) diff --git a/trunk/net/nfc/llcp/llcp.c b/trunk/net/nfc/llcp/llcp.c index 42994fac26d6..92988aa620dc 100644 --- a/trunk/net/nfc/llcp/llcp.c +++ b/trunk/net/nfc/llcp/llcp.c @@ -448,8 +448,6 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, { struct nfc_llcp_sock *sock, *llcp_sock, *n; - pr_debug("ssap dsap %d %d\n", ssap, dsap); - if (ssap == 0 && dsap == 0) return NULL; @@ -785,7 +783,6 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb) { struct nfc_llcp_sock *llcp_sock; - struct sock *sk; u8 dsap, ssap; dsap = nfc_llcp_dsap(skb); @@ -804,14 +801,10 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb) } llcp_sock->dsap = ssap; - sk = &llcp_sock->sk; nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE], skb->len - LLCP_HEADER_SIZE); - sk->sk_state = LLCP_CONNECTED; - sk->sk_state_change(sk); - nfc_llcp_sock_put(llcp_sock); } diff --git a/trunk/net/nfc/llcp/sock.c b/trunk/net/nfc/llcp/sock.c index 3f339b19d140..c13e02ebdef9 100644 --- a/trunk/net/nfc/llcp/sock.c +++ b/trunk/net/nfc/llcp/sock.c @@ -27,42 +27,6 @@ #include "../nfc.h" #include "llcp.h" -static int sock_wait_state(struct sock *sk, int state, unsigned long timeo) -{ - DECLARE_WAITQUEUE(wait, current); - int err = 0; - - pr_debug("sk %p", sk); - - add_wait_queue(sk_sleep(sk), &wait); - set_current_state(TASK_INTERRUPTIBLE); - - while (sk->sk_state != state) { - if (!timeo) { - err = -EINPROGRESS; - break; - } - - if (signal_pending(current)) { - err = sock_intr_errno(timeo); - break; - } - - release_sock(sk); - timeo = schedule_timeout(timeo); - lock_sock(sk); - set_current_state(TASK_INTERRUPTIBLE); - - err = sock_error(sk); - if (err) - break; - } - - __set_current_state(TASK_RUNNING); - remove_wait_queue(sk_sleep(sk), &wait); - return err; -} - static struct proto llcp_sock_proto = { .name = "NFC_LLCP", .owner = THIS_MODULE, @@ -340,24 +304,11 @@ static unsigned int llcp_sock_poll(struct file *file, struct socket *sock, mask |= POLLERR; if (!skb_queue_empty(&sk->sk_receive_queue)) - mask |= POLLIN | POLLRDNORM; + mask |= POLLIN; if (sk->sk_state == LLCP_CLOSED) mask |= POLLHUP; - if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP | POLLIN | POLLRDNORM; - - if (sk->sk_shutdown == SHUTDOWN_MASK) - mask |= POLLHUP; - - if (sock_writeable(sk)) - mask |= POLLOUT | POLLWRNORM | POLLWRBAND; - else - set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); - - pr_debug("mask 0x%x\n", mask); - return mask; } @@ -511,13 +462,9 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, if (ret) goto put_dev; - ret = sock_wait_state(sk, LLCP_CONNECTED, - sock_sndtimeo(sk, flags & O_NONBLOCK)); - if (ret) - goto put_dev; + sk->sk_state = LLCP_CONNECTED; release_sock(sk); - return 0; put_dev: diff --git a/trunk/net/nfc/nci/core.c b/trunk/net/nfc/nci/core.c index d560e6f13072..8737c2089fdd 100644 --- a/trunk/net/nfc/nci/core.c +++ b/trunk/net/nfc/nci/core.c @@ -436,16 +436,16 @@ static void nci_stop_poll(struct nfc_dev *nfc_dev) msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); } -static int nci_activate_target(struct nfc_dev *nfc_dev, - struct nfc_target *target, __u32 protocol) +static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx, + __u32 protocol) { struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); struct nci_rf_discover_select_param param; - struct nfc_target *nci_target = NULL; + struct nfc_target *target = NULL; int i; int rc = 0; - pr_debug("target_idx %d, protocol 0x%x\n", target->idx, protocol); + pr_debug("target_idx %d, protocol 0x%x\n", target_idx, protocol); if ((atomic_read(&ndev->state) != NCI_W4_HOST_SELECT) && (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { @@ -459,25 +459,25 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, } for (i = 0; i < ndev->n_targets; i++) { - if (ndev->targets[i].idx == target->idx) { - nci_target = &ndev->targets[i]; + if (ndev->targets[i].idx == target_idx) { + target = &ndev->targets[i]; break; } } - if (!nci_target) { + if (!target) { pr_err("unable to find the selected target\n"); return -EINVAL; } - if (!(nci_target->supported_protocols & (1 << protocol))) { + if (!(target->supported_protocols & (1 << protocol))) { pr_err("target does not support the requested protocol 0x%x\n", protocol); return -EINVAL; } if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) { - param.rf_discovery_id = nci_target->logical_idx; + param.rf_discovery_id = target->logical_idx; if (protocol == NFC_PROTO_JEWEL) param.rf_protocol = NCI_RF_PROTOCOL_T1T; @@ -501,12 +501,11 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, return rc; } -static void nci_deactivate_target(struct nfc_dev *nfc_dev, - struct nfc_target *target) +static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx) { struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); - pr_debug("target_idx %d\n", target->idx); + pr_debug("target_idx %d\n", target_idx); if (!ndev->target_active_prot) { pr_err("unable to deactivate target, no active target\n"); @@ -521,14 +520,14 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, } } -static int nci_data_exchange(struct nfc_dev *nfc_dev, struct nfc_target *target, +static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) { struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); int rc; - pr_debug("target_idx %d, len %d\n", target->idx, skb->len); + pr_debug("target_idx %d, len %d\n", target_idx, skb->len); if (!ndev->target_active_prot) { pr_err("unable to exchange data, no active target\n"); diff --git a/trunk/net/nfc/nci/data.c b/trunk/net/nfc/nci/data.c index 76c48c5324f8..a0bc326308a5 100644 --- a/trunk/net/nfc/nci/data.c +++ b/trunk/net/nfc/nci/data.c @@ -49,7 +49,7 @@ void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, if (cb) { ndev->data_exchange_cb = NULL; - ndev->data_exchange_cb_context = NULL; + ndev->data_exchange_cb_context = 0; /* forward skb to nfc core */ cb(cb_context, skb, err); @@ -200,10 +200,10 @@ static void nci_add_rx_data_frag(struct nci_dev *ndev, pr_err("error adding room for accumulated rx data\n"); kfree_skb(skb); - skb = NULL; + skb = 0; kfree_skb(ndev->rx_data_reassembly); - ndev->rx_data_reassembly = NULL; + ndev->rx_data_reassembly = 0; err = -ENOMEM; goto exit; @@ -216,7 +216,7 @@ static void nci_add_rx_data_frag(struct nci_dev *ndev, /* third, free old reassembly */ kfree_skb(ndev->rx_data_reassembly); - ndev->rx_data_reassembly = NULL; + ndev->rx_data_reassembly = 0; } if (pbf == NCI_PBF_CONT) { diff --git a/trunk/net/nfc/nci/lib.c b/trunk/net/nfc/nci/lib.c index 6b7fd26c68d9..6a63e5eb483d 100644 --- a/trunk/net/nfc/nci/lib.c +++ b/trunk/net/nfc/nci/lib.c @@ -31,7 +31,6 @@ #include #include -#include /* NCI status codes to Unix errno mapping */ int nci_to_errno(__u8 code) diff --git a/trunk/net/nfc/nci/ntf.c b/trunk/net/nfc/nci/ntf.c index cb2646179e5f..99e1632e6aac 100644 --- a/trunk/net/nfc/nci/ntf.c +++ b/trunk/net/nfc/nci/ntf.c @@ -497,7 +497,7 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, /* drop partial rx data packet */ if (ndev->rx_data_reassembly) { kfree_skb(ndev->rx_data_reassembly); - ndev->rx_data_reassembly = NULL; + ndev->rx_data_reassembly = 0; } /* complete the data exchange transaction, if exists */ diff --git a/trunk/net/nfc/netlink.c b/trunk/net/nfc/netlink.c index 581d419083aa..f1829f6ae9c5 100644 --- a/trunk/net/nfc/netlink.c +++ b/trunk/net/nfc/netlink.c @@ -33,7 +33,7 @@ static struct genl_multicast_group nfc_genl_event_mcgrp = { .name = NFC_GENL_MCAST_EVENT_NAME, }; -static struct genl_family nfc_genl_family = { +struct genl_family nfc_genl_family = { .id = GENL_ID_GENERATE, .hdrsize = 0, .name = NFC_GENL_NAME, @@ -128,7 +128,7 @@ static int nfc_genl_dump_targets(struct sk_buff *skb, cb->args[1] = (long) dev; } - device_lock(&dev->dev); + spin_lock_bh(&dev->targets_lock); cb->seq = dev->targets_generation; @@ -141,7 +141,7 @@ static int nfc_genl_dump_targets(struct sk_buff *skb, i++; } - device_unlock(&dev->dev); + spin_unlock_bh(&dev->targets_lock); cb->args[0] = i; diff --git a/trunk/net/nfc/nfc.h b/trunk/net/nfc/nfc.h index 3dd4232ae664..7d589a81942e 100644 --- a/trunk/net/nfc/nfc.h +++ b/trunk/net/nfc/nfc.h @@ -84,7 +84,7 @@ static inline int nfc_llcp_set_remote_gb(struct nfc_dev *dev, return 0; } -static inline u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *gb_len) +static inline u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *gb_len) { *gb_len = 0; return NULL; diff --git a/trunk/net/wireless/chan.c b/trunk/net/wireless/chan.c index 884801ac4dd0..2fcfe0993ca2 100644 --- a/trunk/net/wireless/chan.c +++ b/trunk/net/wireless/chan.c @@ -45,7 +45,7 @@ rdev_freq_to_chan(struct cfg80211_registered_device *rdev, return chan; } -bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, +int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index a87d43552974..39f2538a46fc 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -664,7 +664,7 @@ void wiphy_unregister(struct wiphy *wiphy) mutex_lock(&rdev->devlist_mtx); __count = rdev->opencount; mutex_unlock(&rdev->devlist_mtx); - __count == 0; })); + __count == 0;})); mutex_lock(&rdev->devlist_mtx); BUG_ON(!list_empty(&rdev->netdev_list)); @@ -776,7 +776,7 @@ static struct device_type wiphy_type = { .name = "wlan", }; -static int cfg80211_netdev_notifier_call(struct notifier_block *nb, +static int cfg80211_netdev_notifier_call(struct notifier_block * nb, unsigned long state, void *ndev) { diff --git a/trunk/net/wireless/core.h b/trunk/net/wireless/core.h index 8523f3878677..3ac2dd00d714 100644 --- a/trunk/net/wireless/core.h +++ b/trunk/net/wireless/core.h @@ -445,6 +445,8 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, int freq, enum nl80211_channel_type channel_type); +u16 cfg80211_calculate_bitrate(struct rate_info *rate); + int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, const u8 *rates, unsigned int n_rates, u32 *mask); diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index 206465dc0cab..b67b1114e25a 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -1179,27 +1179,6 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) wdev->iftype == NL80211_IFTYPE_P2P_GO; } -static bool nl80211_valid_channel_type(struct genl_info *info, - enum nl80211_channel_type *channel_type) -{ - enum nl80211_channel_type tmp; - - if (!info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) - return false; - - tmp = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); - if (tmp != NL80211_CHAN_NO_HT && - tmp != NL80211_CHAN_HT20 && - tmp != NL80211_CHAN_HT40PLUS && - tmp != NL80211_CHAN_HT40MINUS) - return false; - - if (channel_type) - *channel_type = tmp; - - return true; -} - static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, struct genl_info *info) @@ -1214,9 +1193,15 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, if (!nl80211_can_set_dev_channel(wdev)) return -EOPNOTSUPP; - if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && - !nl80211_valid_channel_type(info, &channel_type)) - return -EINVAL; + if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { + channel_type = nla_get_u32(info->attrs[ + NL80211_ATTR_WIPHY_CHANNEL_TYPE]); + if (channel_type != NL80211_CHAN_NO_HT && + channel_type != NL80211_CHAN_HT20 && + channel_type != NL80211_CHAN_HT40PLUS && + channel_type != NL80211_CHAN_HT40MINUS) + return -EINVAL; + } freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); @@ -2425,16 +2410,10 @@ static int parse_station_flags(struct genl_info *info, return -EINVAL; } - for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) { - if (flags[flag]) { + for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) + if (flags[flag]) params->sta_flags_set |= (1< NL80211_STA_FLAG_MAX_OLD_API) - return -EINVAL; - } - } - return 0; } @@ -4933,7 +4912,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { enum nl80211_channel_type channel_type; - if (!nl80211_valid_channel_type(info, &channel_type)) + channel_type = nla_get_u32( + info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); + if (channel_type != NL80211_CHAN_NO_HT && + channel_type != NL80211_CHAN_HT20 && + channel_type != NL80211_CHAN_HT40MINUS && + channel_type != NL80211_CHAN_HT40PLUS) return -EINVAL; if (channel_type != NL80211_CHAN_NO_HT && @@ -5501,9 +5485,15 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)) return -EOPNOTSUPP; - if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && - !nl80211_valid_channel_type(info, &channel_type)) - return -EINVAL; + if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { + channel_type = nla_get_u32( + info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); + if (channel_type != NL80211_CHAN_NO_HT && + channel_type != NL80211_CHAN_HT20 && + channel_type != NL80211_CHAN_HT40PLUS && + channel_type != NL80211_CHAN_HT40MINUS) + return -EINVAL; + } freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); chan = rdev_freq_to_chan(rdev, freq, channel_type); @@ -5774,7 +5764,12 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) } if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { - if (!nl80211_valid_channel_type(info, &channel_type)) + channel_type = nla_get_u32( + info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); + if (channel_type != NL80211_CHAN_NO_HT && + channel_type != NL80211_CHAN_HT20 && + channel_type != NL80211_CHAN_HT40PLUS && + channel_type != NL80211_CHAN_HT40MINUS) return -EINVAL; channel_type_valid = true; } diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index 177df03064cf..6cba00173a2f 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -880,7 +880,7 @@ u16 cfg80211_calculate_bitrate(struct rate_info *rate) return rate->legacy; /* the formula below does only work for MCS values smaller than 32 */ - if (WARN_ON_ONCE(rate->mcs >= 32)) + if (rate->mcs >= 32) return 0; modulation = rate->mcs & 7;