aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-05-22 15:18:06 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-05-22 15:18:06 -0400
commita0d0d1685f9763ab26a394df3ab84026b39a06a7 (patch)
tree4165dc6fd3266977ab4b3fa3b379c47597f97d88 /drivers
parent31a67102f4762df5544bc2dfb34a931233d2a5b2 (diff)
parent05f8f25276ea8c7d41b3649890d6eaf179e67a81 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bcma/core.c3
-rw-r--r--drivers/bcma/driver_pci.c53
-rw-r--r--drivers/bcma/driver_pci_host.c10
-rw-r--r--drivers/bcma/host_pci.c7
-rw-r--r--drivers/bcma/scan.c54
-rw-r--r--drivers/bcma/sprom.c149
-rw-r--r--drivers/bluetooth/ath3k.c6
-rw-r--r--drivers/bluetooth/btmrvl_drv.h3
-rw-r--r--drivers/bluetooth/btmrvl_main.c56
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c112
-rw-r--r--drivers/bluetooth/btusb.c16
-rw-r--r--drivers/bluetooth/hci_ldisc.c2
-rw-r--r--drivers/bluetooth/hci_vhci.c3
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c238
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.h2
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h33
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c12
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_mbox.c45
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_pipe.c11
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c29
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c104
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c17
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c12
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c12
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c94
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h24
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c50
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_rtt.c84
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_rtt.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h9
-rw-r--r--drivers/net/wireless/b43/bus.c6
-rw-r--r--drivers/net/wireless/b43/dma.c2
-rw-r--r--drivers/net/wireless/b43/main.c4
-rw-r--r--drivers/net/wireless/b43legacy/main.c4
-rw-r--r--drivers/net/wireless/b43legacy/phy.c4
-rw-r--r--drivers/net/wireless/b43legacy/radio.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c244
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c32
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c350
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c265
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h37
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/Makefile3
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/aiutils.c479
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/aiutils.h24
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/antsel.c16
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/channel.c7
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c11
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c142
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/nicpci.c826
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/nicpci.h77
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/otp.c410
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/otp.h36
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c67
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c333
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c9
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pub.h228
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/srom.c980
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/srom.h29
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/stf.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-mac80211.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c52
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c5
-rw-r--r--drivers/net/wireless/mwifiex/Makefile2
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c498
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.h2
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c21
-rw-r--r--drivers/net/wireless/mwifiex/decl.h13
-rw-r--r--drivers/net/wireless/mwifiex/fw.h159
-rw-r--r--drivers/net/wireless/mwifiex/ie.c396
-rw-r--r--drivers/net/wireless/mwifiex/init.c1
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h32
-rw-r--r--drivers/net/wireless/mwifiex/join.c26
-rw-r--r--drivers/net/wireless/mwifiex/main.c57
-rw-r--r--drivers/net/wireless/mwifiex/main.h26
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c69
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c8
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c51
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c9
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c432
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c4
-rw-r--r--drivers/net/wireless/rndis_wlan.c14
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c1
-rw-r--r--drivers/net/wireless/ti/wl12xx/Kconfig1
-rw-r--r--drivers/net/wireless/ti/wlcore/Kconfig2
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.c80
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.h30
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.c3
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c8
-rw-r--r--drivers/net/wireless/ti/wlcore/event.c29
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c323
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.c36
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.h4
-rw-r--r--drivers/net/wireless/ti/wlcore/wl12xx.h41
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h6
-rw-r--r--drivers/nfc/Kconfig13
-rw-r--r--drivers/nfc/Makefile1
-rw-r--r--drivers/nfc/pn533.c19
-rw-r--r--drivers/nfc/pn544_hci.c947
-rw-r--r--drivers/ssb/b43_pci_bridge.c2
-rw-r--r--drivers/ssb/pci.c88
109 files changed, 4931 insertions, 4570 deletions
diff --git a/drivers/bcma/core.c b/drivers/bcma/core.c
index 893f6e0c759f..bc6e89212ad3 100644
--- a/drivers/bcma/core.c
+++ b/drivers/bcma/core.c
@@ -30,6 +30,7 @@ void bcma_core_disable(struct bcma_device *core, u32 flags)
30 udelay(10); 30 udelay(10);
31 31
32 bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET); 32 bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
33 bcma_aread32(core, BCMA_RESET_CTL);
33 udelay(1); 34 udelay(1);
34} 35}
35EXPORT_SYMBOL_GPL(bcma_core_disable); 36EXPORT_SYMBOL_GPL(bcma_core_disable);
@@ -77,7 +78,7 @@ void bcma_core_set_clockmode(struct bcma_device *core,
77 pr_err("HT force timeout\n"); 78 pr_err("HT force timeout\n");
78 break; 79 break;
79 case BCMA_CLKMODE_DYNAMIC: 80 case BCMA_CLKMODE_DYNAMIC:
80 pr_warn("Dynamic clockmode not supported yet!\n"); 81 bcma_set32(core, BCMA_CLKCTLST, ~BCMA_CLKCTLST_FORCEHT);
81 break; 82 break;
82 } 83 }
83} 84}
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
index 4d38ae179b48..9a96f14c8f47 100644
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -24,14 +24,12 @@ u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
24 return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA); 24 return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
25} 25}
26 26
27#if 0
28static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data) 27static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
29{ 28{
30 pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address); 29 pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
31 pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR); 30 pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
32 pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data); 31 pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
33} 32}
34#endif
35 33
36static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy) 34static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
37{ 35{
@@ -170,13 +168,50 @@ static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
170 tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN); 168 tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
171} 169}
172 170
171static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc)
172{
173 struct bcma_device *core = pc->core;
174 u16 val16, core_index;
175 uint regoff;
176
177 regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET);
178 core_index = (u16)core->core_index;
179
180 val16 = pcicore_read16(pc, regoff);
181 if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT)
182 != core_index) {
183 val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) |
184 (val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK);
185 pcicore_write16(pc, regoff, val16);
186 }
187}
188
189/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
190/* Needs to happen when coming out of 'standby'/'hibernate' */
191static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
192{
193 u16 val16;
194 uint regoff;
195
196 regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_MISC_CONFIG);
197
198 val16 = pcicore_read16(pc, regoff);
199
200 if (!(val16 & BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST)) {
201 val16 |= BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST;
202 pcicore_write16(pc, regoff, val16);
203 }
204}
205
173/************************************************** 206/**************************************************
174 * Init. 207 * Init.
175 **************************************************/ 208 **************************************************/
176 209
177static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc) 210static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
178{ 211{
212 bcma_core_pci_fixcfg(pc);
179 bcma_pcicore_serdes_workaround(pc); 213 bcma_pcicore_serdes_workaround(pc);
214 bcma_core_pci_config_fixup(pc);
180} 215}
181 216
182void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc) 217void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
@@ -224,3 +259,17 @@ out:
224 return err; 259 return err;
225} 260}
226EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl); 261EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
262
263void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
264{
265 u32 w;
266
267 w = bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
268 if (extend)
269 w |= BCMA_CORE_PCI_ASPMTIMER_EXTEND;
270 else
271 w &= ~BCMA_CORE_PCI_ASPMTIMER_EXTEND;
272 bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
273 bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
274}
275EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
index d2097a11c3c7..b9a86edfec39 100644
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
@@ -119,7 +119,7 @@ static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
119 if (unlikely(!addr)) 119 if (unlikely(!addr))
120 goto out; 120 goto out;
121 err = -ENOMEM; 121 err = -ENOMEM;
122 mmio = ioremap_nocache(addr, len); 122 mmio = ioremap_nocache(addr, sizeof(val));
123 if (!mmio) 123 if (!mmio)
124 goto out; 124 goto out;
125 125
@@ -171,7 +171,7 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
171 addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0; 171 addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
172 addr |= (func << 8); 172 addr |= (func << 8);
173 addr |= (off & 0xfc); 173 addr |= (off & 0xfc);
174 mmio = ioremap_nocache(addr, len); 174 mmio = ioremap_nocache(addr, sizeof(val));
175 if (!mmio) 175 if (!mmio)
176 goto out; 176 goto out;
177 } 177 }
@@ -180,7 +180,7 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
180 if (unlikely(!addr)) 180 if (unlikely(!addr))
181 goto out; 181 goto out;
182 err = -ENOMEM; 182 err = -ENOMEM;
183 mmio = ioremap_nocache(addr, len); 183 mmio = ioremap_nocache(addr, sizeof(val));
184 if (!mmio) 184 if (!mmio)
185 goto out; 185 goto out;
186 186
@@ -491,8 +491,8 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
491 /* Ok, ready to run, register it to the system. 491 /* Ok, ready to run, register it to the system.
492 * The following needs change, if we want to port hostmode 492 * The following needs change, if we want to port hostmode
493 * to non-MIPS platform. */ 493 * to non-MIPS platform. */
494 io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM, 494 io_map_base = (unsigned long)ioremap_nocache(pc_host->mem_resource.start,
495 0x04000000); 495 resource_size(&pc_host->mem_resource));
496 pc_host->pci_controller.io_map_base = io_map_base; 496 pc_host->pci_controller.io_map_base = io_map_base;
497 set_io_port_base(pc_host->pci_controller.io_map_base); 497 set_io_port_base(pc_host->pci_controller.io_map_base);
498 /* Give some time to the PCI controller to configure itself with the new 498 /* Give some time to the PCI controller to configure itself with the new
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index e3928d68802b..6c05cf470f96 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -201,6 +201,9 @@ static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
201 bus->hosttype = BCMA_HOSTTYPE_PCI; 201 bus->hosttype = BCMA_HOSTTYPE_PCI;
202 bus->ops = &bcma_host_pci_ops; 202 bus->ops = &bcma_host_pci_ops;
203 203
204 bus->boardinfo.vendor = bus->host_pci->subsystem_vendor;
205 bus->boardinfo.type = bus->host_pci->subsystem_device;
206
204 /* Register */ 207 /* Register */
205 err = bcma_bus_register(bus); 208 err = bcma_bus_register(bus);
206 if (err) 209 if (err)
@@ -222,7 +225,7 @@ err_kfree_bus:
222 return err; 225 return err;
223} 226}
224 227
225static void bcma_host_pci_remove(struct pci_dev *dev) 228static void __devexit bcma_host_pci_remove(struct pci_dev *dev)
226{ 229{
227 struct bcma_bus *bus = pci_get_drvdata(dev); 230 struct bcma_bus *bus = pci_get_drvdata(dev);
228 231
@@ -277,7 +280,7 @@ static struct pci_driver bcma_pci_bridge_driver = {
277 .name = "bcma-pci-bridge", 280 .name = "bcma-pci-bridge",
278 .id_table = bcma_pci_bridge_tbl, 281 .id_table = bcma_pci_bridge_tbl,
279 .probe = bcma_host_pci_probe, 282 .probe = bcma_host_pci_probe,
280 .remove = bcma_host_pci_remove, 283 .remove = __devexit_p(bcma_host_pci_remove),
281 .driver.pm = BCMA_PM_OPS, 284 .driver.pm = BCMA_PM_OPS,
282}; 285};
283 286
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index f94cccccfa56..e19e987bc9e1 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -19,7 +19,14 @@ struct bcma_device_id_name {
19 u16 id; 19 u16 id;
20 const char *name; 20 const char *name;
21}; 21};
22struct bcma_device_id_name bcma_device_names[] = { 22
23static const struct bcma_device_id_name bcma_arm_device_names[] = {
24 { BCMA_CORE_ARM_1176, "ARM 1176" },
25 { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
26 { BCMA_CORE_ARM_CM3, "ARM CM3" },
27};
28
29static const struct bcma_device_id_name bcma_bcm_device_names[] = {
23 { BCMA_CORE_OOB_ROUTER, "OOB Router" }, 30 { BCMA_CORE_OOB_ROUTER, "OOB Router" },
24 { BCMA_CORE_INVALID, "Invalid" }, 31 { BCMA_CORE_INVALID, "Invalid" },
25 { BCMA_CORE_CHIPCOMMON, "ChipCommon" }, 32 { BCMA_CORE_CHIPCOMMON, "ChipCommon" },
@@ -27,7 +34,6 @@ struct bcma_device_id_name bcma_device_names[] = {
27 { BCMA_CORE_SRAM, "SRAM" }, 34 { BCMA_CORE_SRAM, "SRAM" },
28 { BCMA_CORE_SDRAM, "SDRAM" }, 35 { BCMA_CORE_SDRAM, "SDRAM" },
29 { BCMA_CORE_PCI, "PCI" }, 36 { BCMA_CORE_PCI, "PCI" },
30 { BCMA_CORE_MIPS, "MIPS" },
31 { BCMA_CORE_ETHERNET, "Fast Ethernet" }, 37 { BCMA_CORE_ETHERNET, "Fast Ethernet" },
32 { BCMA_CORE_V90, "V90" }, 38 { BCMA_CORE_V90, "V90" },
33 { BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" }, 39 { BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
@@ -44,7 +50,6 @@ struct bcma_device_id_name bcma_device_names[] = {
44 { BCMA_CORE_PHY_A, "PHY A" }, 50 { BCMA_CORE_PHY_A, "PHY A" },
45 { BCMA_CORE_PHY_B, "PHY B" }, 51 { BCMA_CORE_PHY_B, "PHY B" },
46 { BCMA_CORE_PHY_G, "PHY G" }, 52 { BCMA_CORE_PHY_G, "PHY G" },
47 { BCMA_CORE_MIPS_3302, "MIPS 3302" },
48 { BCMA_CORE_USB11_HOST, "USB 1.1 Host" }, 53 { BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
49 { BCMA_CORE_USB11_DEV, "USB 1.1 Device" }, 54 { BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
50 { BCMA_CORE_USB20_HOST, "USB 2.0 Host" }, 55 { BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
@@ -58,15 +63,11 @@ struct bcma_device_id_name bcma_device_names[] = {
58 { BCMA_CORE_PHY_N, "PHY N" }, 63 { BCMA_CORE_PHY_N, "PHY N" },
59 { BCMA_CORE_SRAM_CTL, "SRAM Controller" }, 64 { BCMA_CORE_SRAM_CTL, "SRAM Controller" },
60 { BCMA_CORE_MINI_MACPHY, "Mini MACPHY" }, 65 { BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
61 { BCMA_CORE_ARM_1176, "ARM 1176" },
62 { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
63 { BCMA_CORE_PHY_LP, "PHY LP" }, 66 { BCMA_CORE_PHY_LP, "PHY LP" },
64 { BCMA_CORE_PMU, "PMU" }, 67 { BCMA_CORE_PMU, "PMU" },
65 { BCMA_CORE_PHY_SSN, "PHY SSN" }, 68 { BCMA_CORE_PHY_SSN, "PHY SSN" },
66 { BCMA_CORE_SDIO_DEV, "SDIO Device" }, 69 { BCMA_CORE_SDIO_DEV, "SDIO Device" },
67 { BCMA_CORE_ARM_CM3, "ARM CM3" },
68 { BCMA_CORE_PHY_HT, "PHY HT" }, 70 { BCMA_CORE_PHY_HT, "PHY HT" },
69 { BCMA_CORE_MIPS_74K, "MIPS 74K" },
70 { BCMA_CORE_MAC_GBIT, "GBit MAC" }, 71 { BCMA_CORE_MAC_GBIT, "GBit MAC" },
71 { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" }, 72 { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
72 { BCMA_CORE_PCIE_RC, "PCIe Root Complex" }, 73 { BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
@@ -79,16 +80,41 @@ struct bcma_device_id_name bcma_device_names[] = {
79 { BCMA_CORE_SHIM, "SHIM" }, 80 { BCMA_CORE_SHIM, "SHIM" },
80 { BCMA_CORE_DEFAULT, "Default" }, 81 { BCMA_CORE_DEFAULT, "Default" },
81}; 82};
82const char *bcma_device_name(struct bcma_device_id *id) 83
84static const struct bcma_device_id_name bcma_mips_device_names[] = {
85 { BCMA_CORE_MIPS, "MIPS" },
86 { BCMA_CORE_MIPS_3302, "MIPS 3302" },
87 { BCMA_CORE_MIPS_74K, "MIPS 74K" },
88};
89
90static const char *bcma_device_name(const struct bcma_device_id *id)
83{ 91{
84 int i; 92 const struct bcma_device_id_name *names;
93 int size, i;
94
95 /* search manufacturer specific names */
96 switch (id->manuf) {
97 case BCMA_MANUF_ARM:
98 names = bcma_arm_device_names;
99 size = ARRAY_SIZE(bcma_arm_device_names);
100 break;
101 case BCMA_MANUF_BCM:
102 names = bcma_bcm_device_names;
103 size = ARRAY_SIZE(bcma_bcm_device_names);
104 break;
105 case BCMA_MANUF_MIPS:
106 names = bcma_mips_device_names;
107 size = ARRAY_SIZE(bcma_mips_device_names);
108 break;
109 default:
110 return "UNKNOWN";
111 }
85 112
86 if (id->manuf == BCMA_MANUF_BCM) { 113 for (i = 0; i < size; i++) {
87 for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) { 114 if (names[i].id == id->id)
88 if (bcma_device_names[i].id == id->id) 115 return names[i].name;
89 return bcma_device_names[i].name;
90 }
91 } 116 }
117
92 return "UNKNOWN"; 118 return "UNKNOWN";
93} 119}
94 120
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 3e2a6002aae6..c7f93359acb0 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -181,6 +181,22 @@ static int bcma_sprom_valid(const u16 *sprom)
181#define SPEX(_field, _offset, _mask, _shift) \ 181#define SPEX(_field, _offset, _mask, _shift) \
182 bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift)) 182 bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
183 183
184#define SPEX32(_field, _offset, _mask, _shift) \
185 bus->sprom._field = ((((u32)sprom[SPOFF((_offset)+2)] << 16 | \
186 sprom[SPOFF(_offset)]) & (_mask)) >> (_shift))
187
188#define SPEX_ARRAY8(_field, _offset, _mask, _shift) \
189 do { \
190 SPEX(_field[0], _offset + 0, _mask, _shift); \
191 SPEX(_field[1], _offset + 2, _mask, _shift); \
192 SPEX(_field[2], _offset + 4, _mask, _shift); \
193 SPEX(_field[3], _offset + 6, _mask, _shift); \
194 SPEX(_field[4], _offset + 8, _mask, _shift); \
195 SPEX(_field[5], _offset + 10, _mask, _shift); \
196 SPEX(_field[6], _offset + 12, _mask, _shift); \
197 SPEX(_field[7], _offset + 14, _mask, _shift); \
198 } while (0)
199
184static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) 200static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
185{ 201{
186 u16 v, o; 202 u16 v, o;
@@ -243,7 +259,8 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
243 SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0); 259 SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
244 SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0); 260 SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
245 261
246 SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0); 262 SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
263 SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
247 264
248 /* Extract cores power info info */ 265 /* Extract cores power info info */
249 for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { 266 for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
@@ -298,6 +315,136 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
298 SSB_SROM8_FEM_TR_ISO_SHIFT); 315 SSB_SROM8_FEM_TR_ISO_SHIFT);
299 SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT, 316 SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
300 SSB_SROM8_FEM_ANTSWLUT_SHIFT); 317 SSB_SROM8_FEM_ANTSWLUT_SHIFT);
318
319 SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
320 SSB_SPROM8_ANTAVAIL_A_SHIFT);
321 SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
322 SSB_SPROM8_ANTAVAIL_BG_SHIFT);
323 SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
324 SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
325 SSB_SPROM8_ITSSI_BG_SHIFT);
326 SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
327 SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
328 SSB_SPROM8_ITSSI_A_SHIFT);
329 SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
330 SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
331 SSB_SPROM8_MAXP_AL_SHIFT);
332 SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
333 SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
334 SSB_SPROM8_GPIOA_P1_SHIFT);
335 SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
336 SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
337 SSB_SPROM8_GPIOB_P3_SHIFT);
338 SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
339 SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
340 SSB_SPROM8_TRI5G_SHIFT);
341 SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
342 SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
343 SSB_SPROM8_TRI5GH_SHIFT);
344 SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G,
345 SSB_SPROM8_RXPO2G_SHIFT);
346 SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
347 SSB_SPROM8_RXPO5G_SHIFT);
348 SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
349 SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
350 SSB_SPROM8_RSSISMC2G_SHIFT);
351 SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
352 SSB_SPROM8_RSSISAV2G_SHIFT);
353 SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
354 SSB_SPROM8_BXA2G_SHIFT);
355 SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
356 SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
357 SSB_SPROM8_RSSISMC5G_SHIFT);
358 SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
359 SSB_SPROM8_RSSISAV5G_SHIFT);
360 SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
361 SSB_SPROM8_BXA5G_SHIFT);
362
363 SPEX(pa0b0, SSB_SPROM8_PA0B0, ~0, 0);
364 SPEX(pa0b1, SSB_SPROM8_PA0B1, ~0, 0);
365 SPEX(pa0b2, SSB_SPROM8_PA0B2, ~0, 0);
366 SPEX(pa1b0, SSB_SPROM8_PA1B0, ~0, 0);
367 SPEX(pa1b1, SSB_SPROM8_PA1B1, ~0, 0);
368 SPEX(pa1b2, SSB_SPROM8_PA1B2, ~0, 0);
369 SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, ~0, 0);
370 SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, ~0, 0);
371 SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, ~0, 0);
372 SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, ~0, 0);
373 SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, ~0, 0);
374 SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, ~0, 0);
375 SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, ~0, 0);
376 SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, ~0, 0);
377 SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, ~0, 0);
378 SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, ~0, 0);
379 SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
380
381 /* Extract the antenna gain values. */
382 SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
383 SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
384 SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
385 SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
386 SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
387 SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
388 SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
389 SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
390
391 SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
392 SSB_SPROM8_LEDDC_ON_SHIFT);
393 SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
394 SSB_SPROM8_LEDDC_OFF_SHIFT);
395
396 SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
397 SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
398 SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
399 SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
400 SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
401 SSB_SPROM8_TXRXC_SWITCH_SHIFT);
402
403 SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
404
405 SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
406 SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
407 SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
408 SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
409
410 SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
411 SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
412 SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
413 SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
414 SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
415 SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
416 SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
417 SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
418 SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
419 SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
420 SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
421 SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
422 SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
423 SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
424 SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
425 SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
426 SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
427 SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
428 SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
429 SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
430
431 SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
432 SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
433 SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
434 SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
435
436 SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
437 SSB_SPROM8_THERMAL_TRESH_SHIFT);
438 SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
439 SSB_SPROM8_THERMAL_OFFSET_SHIFT);
440 SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
441 SSB_SPROM8_TEMPDELTA_PHYCAL,
442 SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
443 SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
444 SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
445 SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
446 SSB_SPROM8_TEMPDELTA_HYSTERESIS,
447 SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
301} 448}
302 449
303/* 450/*
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 57fd867553d7..aba22b2f12d6 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -81,6 +81,9 @@ static struct usb_device_id ath3k_table[] = {
81 /* Atheros AR5BBU12 with sflash firmware */ 81 /* Atheros AR5BBU12 with sflash firmware */
82 { USB_DEVICE(0x0489, 0xE02C) }, 82 { USB_DEVICE(0x0489, 0xE02C) },
83 83
84 /* Atheros AR5BBU22 with sflash firmware */
85 { USB_DEVICE(0x0489, 0xE03C) },
86
84 { } /* Terminating entry */ 87 { } /* Terminating entry */
85}; 88};
86 89
@@ -99,6 +102,9 @@ static struct usb_device_id ath3k_blist_tbl[] = {
99 { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, 102 { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
100 { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, 103 { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
101 104
105 /* Atheros AR5BBU22 with sflash firmware */
106 { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
107
102 { } /* Terminating entry */ 108 { } /* Terminating entry */
103}; 109};
104 110
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h
index 90bda50dc446..94f2d65131c4 100644
--- a/drivers/bluetooth/btmrvl_drv.h
+++ b/drivers/bluetooth/btmrvl_drv.h
@@ -67,6 +67,7 @@ struct btmrvl_adapter {
67 u8 wakeup_tries; 67 u8 wakeup_tries;
68 wait_queue_head_t cmd_wait_q; 68 wait_queue_head_t cmd_wait_q;
69 u8 cmd_complete; 69 u8 cmd_complete;
70 bool is_suspended;
70}; 71};
71 72
72struct btmrvl_private { 73struct btmrvl_private {
@@ -139,8 +140,10 @@ void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb);
139int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); 140int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
140 141
141int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); 142int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd);
143int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
142int btmrvl_enable_ps(struct btmrvl_private *priv); 144int btmrvl_enable_ps(struct btmrvl_private *priv);
143int btmrvl_prepare_command(struct btmrvl_private *priv); 145int btmrvl_prepare_command(struct btmrvl_private *priv);
146int btmrvl_enable_hs(struct btmrvl_private *priv);
144 147
145#ifdef CONFIG_DEBUG_FS 148#ifdef CONFIG_DEBUG_FS
146void btmrvl_debugfs_init(struct hci_dev *hdev); 149void btmrvl_debugfs_init(struct hci_dev *hdev);
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index d1209adc882d..681ca9d18e12 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -200,6 +200,36 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
200} 200}
201EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd); 201EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
202 202
203int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
204{
205 struct sk_buff *skb;
206 struct btmrvl_cmd *cmd;
207
208 skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
209 if (!skb) {
210 BT_ERR("No free skb");
211 return -ENOMEM;
212 }
213
214 cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
215 cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF,
216 BT_CMD_HOST_SLEEP_CONFIG));
217 cmd->length = 2;
218 cmd->data[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
219 cmd->data[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
220
221 bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
222
223 skb->dev = (void *) priv->btmrvl_dev.hcidev;
224 skb_queue_head(&priv->adapter->tx_queue, skb);
225
226 BT_DBG("Queue HSCFG Command, gpio=0x%x, gap=0x%x", cmd->data[0],
227 cmd->data[1]);
228
229 return 0;
230}
231EXPORT_SYMBOL_GPL(btmrvl_send_hscfg_cmd);
232
203int btmrvl_enable_ps(struct btmrvl_private *priv) 233int btmrvl_enable_ps(struct btmrvl_private *priv)
204{ 234{
205 struct sk_buff *skb; 235 struct sk_buff *skb;
@@ -232,7 +262,7 @@ int btmrvl_enable_ps(struct btmrvl_private *priv)
232} 262}
233EXPORT_SYMBOL_GPL(btmrvl_enable_ps); 263EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
234 264
235static int btmrvl_enable_hs(struct btmrvl_private *priv) 265int btmrvl_enable_hs(struct btmrvl_private *priv)
236{ 266{
237 struct sk_buff *skb; 267 struct sk_buff *skb;
238 struct btmrvl_cmd *cmd; 268 struct btmrvl_cmd *cmd;
@@ -268,35 +298,15 @@ static int btmrvl_enable_hs(struct btmrvl_private *priv)
268 298
269 return ret; 299 return ret;
270} 300}
301EXPORT_SYMBOL_GPL(btmrvl_enable_hs);
271 302
272int btmrvl_prepare_command(struct btmrvl_private *priv) 303int btmrvl_prepare_command(struct btmrvl_private *priv)
273{ 304{
274 struct sk_buff *skb = NULL;
275 struct btmrvl_cmd *cmd;
276 int ret = 0; 305 int ret = 0;
277 306
278 if (priv->btmrvl_dev.hscfgcmd) { 307 if (priv->btmrvl_dev.hscfgcmd) {
279 priv->btmrvl_dev.hscfgcmd = 0; 308 priv->btmrvl_dev.hscfgcmd = 0;
280 309 btmrvl_send_hscfg_cmd(priv);
281 skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
282 if (skb == NULL) {
283 BT_ERR("No free skb");
284 return -ENOMEM;
285 }
286
287 cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
288 cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_CONFIG));
289 cmd->length = 2;
290 cmd->data[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
291 cmd->data[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
292
293 bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
294
295 skb->dev = (void *) priv->btmrvl_dev.hcidev;
296 skb_queue_head(&priv->adapter->tx_queue, skb);
297
298 BT_DBG("Queue HSCFG Command, gpio=0x%x, gap=0x%x",
299 cmd->data[0], cmd->data[1]);
300 } 310 }
301 311
302 if (priv->btmrvl_dev.pscmd) { 312 if (priv->btmrvl_dev.pscmd) {
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 27b74b0d547b..a853244e7fd7 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -339,9 +339,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
339 339
340done: 340done:
341 kfree(tmphlprbuf); 341 kfree(tmphlprbuf);
342 if (fw_helper) 342 release_firmware(fw_helper);
343 release_firmware(fw_helper);
344
345 return ret; 343 return ret;
346} 344}
347 345
@@ -484,10 +482,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
484 482
485done: 483done:
486 kfree(tmpfwbuf); 484 kfree(tmpfwbuf);
487 485 release_firmware(fw_firmware);
488 if (fw_firmware)
489 release_firmware(fw_firmware);
490
491 return ret; 486 return ret;
492} 487}
493 488
@@ -1013,6 +1008,9 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
1013 priv->btmrvl_dev.psmode = 1; 1008 priv->btmrvl_dev.psmode = 1;
1014 btmrvl_enable_ps(priv); 1009 btmrvl_enable_ps(priv);
1015 1010
1011 priv->btmrvl_dev.gpio_gap = 0xffff;
1012 btmrvl_send_hscfg_cmd(priv);
1013
1016 return 0; 1014 return 0;
1017 1015
1018disable_host_int: 1016disable_host_int:
@@ -1048,11 +1046,111 @@ static void btmrvl_sdio_remove(struct sdio_func *func)
1048 } 1046 }
1049} 1047}
1050 1048
1049static int btmrvl_sdio_suspend(struct device *dev)
1050{
1051 struct sdio_func *func = dev_to_sdio_func(dev);
1052 struct btmrvl_sdio_card *card;
1053 struct btmrvl_private *priv;
1054 mmc_pm_flag_t pm_flags;
1055 struct hci_dev *hcidev;
1056
1057 if (func) {
1058 pm_flags = sdio_get_host_pm_caps(func);
1059 BT_DBG("%s: suspend: PM flags = 0x%x", sdio_func_id(func),
1060 pm_flags);
1061 if (!(pm_flags & MMC_PM_KEEP_POWER)) {
1062 BT_ERR("%s: cannot remain alive while suspended",
1063 sdio_func_id(func));
1064 return -ENOSYS;
1065 }
1066 card = sdio_get_drvdata(func);
1067 if (!card || !card->priv) {
1068 BT_ERR("card or priv structure is not valid");
1069 return 0;
1070 }
1071 } else {
1072 BT_ERR("sdio_func is not specified");
1073 return 0;
1074 }
1075
1076 priv = card->priv;
1077
1078 if (priv->adapter->hs_state != HS_ACTIVATED) {
1079 if (btmrvl_enable_hs(priv)) {
1080 BT_ERR("HS not actived, suspend failed!");
1081 return -EBUSY;
1082 }
1083 }
1084 hcidev = priv->btmrvl_dev.hcidev;
1085 BT_DBG("%s: SDIO suspend", hcidev->name);
1086 hci_suspend_dev(hcidev);
1087 skb_queue_purge(&priv->adapter->tx_queue);
1088
1089 priv->adapter->is_suspended = true;
1090
1091 /* We will keep the power when hs enabled successfully */
1092 if (priv->adapter->hs_state == HS_ACTIVATED) {
1093 BT_DBG("suspend with MMC_PM_KEEP_POWER");
1094 return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
1095 } else {
1096 BT_DBG("suspend without MMC_PM_KEEP_POWER");
1097 return 0;
1098 }
1099}
1100
1101static int btmrvl_sdio_resume(struct device *dev)
1102{
1103 struct sdio_func *func = dev_to_sdio_func(dev);
1104 struct btmrvl_sdio_card *card;
1105 struct btmrvl_private *priv;
1106 mmc_pm_flag_t pm_flags;
1107 struct hci_dev *hcidev;
1108
1109 if (func) {
1110 pm_flags = sdio_get_host_pm_caps(func);
1111 BT_DBG("%s: resume: PM flags = 0x%x", sdio_func_id(func),
1112 pm_flags);
1113 card = sdio_get_drvdata(func);
1114 if (!card || !card->priv) {
1115 BT_ERR("card or priv structure is not valid");
1116 return 0;
1117 }
1118 } else {
1119 BT_ERR("sdio_func is not specified");
1120 return 0;
1121 }
1122 priv = card->priv;
1123
1124 if (!priv->adapter->is_suspended) {
1125 BT_DBG("device already resumed");
1126 return 0;
1127 }
1128
1129 priv->adapter->is_suspended = false;
1130 hcidev = priv->btmrvl_dev.hcidev;
1131 BT_DBG("%s: SDIO resume", hcidev->name);
1132 hci_resume_dev(hcidev);
1133 priv->hw_wakeup_firmware(priv);
1134 priv->adapter->hs_state = HS_DEACTIVATED;
1135 BT_DBG("%s: HS DEACTIVATED in resume!", hcidev->name);
1136
1137 return 0;
1138}
1139
1140static const struct dev_pm_ops btmrvl_sdio_pm_ops = {
1141 .suspend = btmrvl_sdio_suspend,
1142 .resume = btmrvl_sdio_resume,
1143};
1144
1051static struct sdio_driver bt_mrvl_sdio = { 1145static struct sdio_driver bt_mrvl_sdio = {
1052 .name = "btmrvl_sdio", 1146 .name = "btmrvl_sdio",
1053 .id_table = btmrvl_sdio_ids, 1147 .id_table = btmrvl_sdio_ids,
1054 .probe = btmrvl_sdio_probe, 1148 .probe = btmrvl_sdio_probe,
1055 .remove = btmrvl_sdio_remove, 1149 .remove = btmrvl_sdio_remove,
1150 .drv = {
1151 .owner = THIS_MODULE,
1152 .pm = &btmrvl_sdio_pm_ops,
1153 }
1056}; 1154};
1057 1155
1058static int __init btmrvl_sdio_init_module(void) 1156static int __init btmrvl_sdio_init_module(void)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 9217121362e1..cb480f1f81b1 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -143,6 +143,9 @@ static struct usb_device_id blacklist_table[] = {
143 /* Atheros AR5BBU12 with sflash firmware */ 143 /* Atheros AR5BBU12 with sflash firmware */
144 { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, 144 { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
145 145
146 /* Atheros AR5BBU12 with sflash firmware */
147 { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
148
146 /* Broadcom BCM2035 */ 149 /* Broadcom BCM2035 */
147 { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, 150 { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
148 { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, 151 { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
@@ -855,6 +858,7 @@ static void btusb_work(struct work_struct *work)
855{ 858{
856 struct btusb_data *data = container_of(work, struct btusb_data, work); 859 struct btusb_data *data = container_of(work, struct btusb_data, work);
857 struct hci_dev *hdev = data->hdev; 860 struct hci_dev *hdev = data->hdev;
861 int new_alts;
858 int err; 862 int err;
859 863
860 if (hdev->conn_hash.sco_num > 0) { 864 if (hdev->conn_hash.sco_num > 0) {
@@ -868,11 +872,19 @@ static void btusb_work(struct work_struct *work)
868 872
869 set_bit(BTUSB_DID_ISO_RESUME, &data->flags); 873 set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
870 } 874 }
871 if (data->isoc_altsetting != 2) { 875
876 if (hdev->voice_setting & 0x0020) {
877 static const int alts[3] = { 2, 4, 5 };
878 new_alts = alts[hdev->conn_hash.sco_num - 1];
879 } else {
880 new_alts = hdev->conn_hash.sco_num;
881 }
882
883 if (data->isoc_altsetting != new_alts) {
872 clear_bit(BTUSB_ISOC_RUNNING, &data->flags); 884 clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
873 usb_kill_anchored_urbs(&data->isoc_anchor); 885 usb_kill_anchored_urbs(&data->isoc_anchor);
874 886
875 if (__set_isoc_interface(hdev, 2) < 0) 887 if (__set_isoc_interface(hdev, new_alts) < 0)
876 return; 888 return;
877 } 889 }
878 890
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 98a8c05d4f23..e564579a6115 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -388,7 +388,7 @@ static int hci_uart_register_dev(struct hci_uart *hu)
388 hdev->close = hci_uart_close; 388 hdev->close = hci_uart_close;
389 hdev->flush = hci_uart_flush; 389 hdev->flush = hci_uart_flush;
390 hdev->send = hci_uart_send_frame; 390 hdev->send = hci_uart_send_frame;
391 hdev->parent = hu->tty->dev; 391 SET_HCIDEV_DEV(hdev, hu->tty->dev);
392 392
393 if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags)) 393 if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
394 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); 394 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 158bfe507da7..3f72595a6017 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -252,8 +252,9 @@ static int vhci_open(struct inode *inode, struct file *file)
252 } 252 }
253 253
254 file->private_data = data; 254 file->private_data = data;
255 nonseekable_open(inode, file);
255 256
256 return nonseekable_open(inode, file); 257 return 0;
257} 258}
258 259
259static int vhci_release(struct inode *inode, struct file *file) 260static int vhci_release(struct inode *inode, struct file *file)
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 28a65d3a03d0..b869a358ce43 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -693,8 +693,8 @@ ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
693 ie, 2 + vif->ssid_len + beacon_ie_len, 693 ie, 2 + vif->ssid_len + beacon_ie_len,
694 0, GFP_KERNEL); 694 0, GFP_KERNEL);
695 if (bss) 695 if (bss)
696 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added bss %pM to " 696 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
697 "cfg80211\n", bssid); 697 "added bss %pM to cfg80211\n", bssid);
698 kfree(ie); 698 kfree(ie);
699 } else 699 } else
700 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n"); 700 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
@@ -882,6 +882,32 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
882 vif->sme_state = SME_DISCONNECTED; 882 vif->sme_state = SME_DISCONNECTED;
883} 883}
884 884
885static int ath6kl_set_probed_ssids(struct ath6kl *ar,
886 struct ath6kl_vif *vif,
887 struct cfg80211_ssid *ssids, int n_ssids)
888{
889 u8 i;
890
891 if (n_ssids > MAX_PROBED_SSID_INDEX)
892 return -EINVAL;
893
894 for (i = 0; i < n_ssids; i++) {
895 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
896 ssids[i].ssid_len ?
897 SPECIFIC_SSID_FLAG : ANY_SSID_FLAG,
898 ssids[i].ssid_len,
899 ssids[i].ssid);
900 }
901
902 /* Make sure no old entries are left behind */
903 for (i = n_ssids; i < MAX_PROBED_SSID_INDEX; i++) {
904 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
905 DISABLE_SSID_FLAG, 0, NULL);
906 }
907
908 return 0;
909}
910
885static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, 911static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
886 struct cfg80211_scan_request *request) 912 struct cfg80211_scan_request *request)
887{ 913{
@@ -899,36 +925,25 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
899 925
900 if (!ar->usr_bss_filter) { 926 if (!ar->usr_bss_filter) {
901 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); 927 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
902 ret = ath6kl_wmi_bssfilter_cmd( 928 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
903 ar->wmi, vif->fw_vif_idx, 929 ALL_BSS_FILTER, 0);
904 (test_bit(CONNECTED, &vif->flags) ?
905 ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
906 if (ret) { 930 if (ret) {
907 ath6kl_err("couldn't set bss filtering\n"); 931 ath6kl_err("couldn't set bss filtering\n");
908 return ret; 932 return ret;
909 } 933 }
910 } 934 }
911 935
912 if (request->n_ssids && request->ssids[0].ssid_len) { 936 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
913 u8 i; 937 request->n_ssids);
914 938 if (ret < 0)
915 if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) 939 return ret;
916 request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
917
918 for (i = 0; i < request->n_ssids; i++)
919 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
920 i + 1, SPECIFIC_SSID_FLAG,
921 request->ssids[i].ssid_len,
922 request->ssids[i].ssid);
923 }
924 940
925 /* this also clears IE in fw if it's not set */ 941 /* this also clears IE in fw if it's not set */
926 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, 942 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
927 WMI_FRAME_PROBE_REQ, 943 WMI_FRAME_PROBE_REQ,
928 request->ie, request->ie_len); 944 request->ie, request->ie_len);
929 if (ret) { 945 if (ret) {
930 ath6kl_err("failed to set Probe Request appie for " 946 ath6kl_err("failed to set Probe Request appie for scan");
931 "scan");
932 return ret; 947 return ret;
933 } 948 }
934 949
@@ -945,8 +960,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
945 960
946 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL); 961 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
947 if (channels == NULL) { 962 if (channels == NULL) {
948 ath6kl_warn("failed to set scan channels, " 963 ath6kl_warn("failed to set scan channels, scan all channels");
949 "scan all channels");
950 n_channels = 0; 964 n_channels = 0;
951 } 965 }
952 966
@@ -1018,6 +1032,20 @@ out:
1018 vif->scan_req = NULL; 1032 vif->scan_req = NULL;
1019} 1033}
1020 1034
1035void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1036 enum wmi_phy_mode mode)
1037{
1038 enum nl80211_channel_type type;
1039
1040 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1041 "channel switch notify nw_type %d freq %d mode %d\n",
1042 vif->nw_type, freq, mode);
1043
1044 type = (mode == WMI_11G_HT20) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT;
1045
1046 cfg80211_ch_switch_notify(vif->ndev, freq, type);
1047}
1048
1021static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, 1049static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1022 u8 key_index, bool pairwise, 1050 u8 key_index, bool pairwise,
1023 const u8 *mac_addr, 1051 const u8 *mac_addr,
@@ -1111,9 +1139,8 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1111 ar->ap_mode_bkey.key_len = key->key_len; 1139 ar->ap_mode_bkey.key_len = key->key_len;
1112 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len); 1140 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1113 if (!test_bit(CONNECTED, &vif->flags)) { 1141 if (!test_bit(CONNECTED, &vif->flags)) {
1114 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group " 1142 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1115 "key configuration until AP mode has been " 1143 "Delay initial group key configuration until AP mode has been started\n");
1116 "started\n");
1117 /* 1144 /*
1118 * The key will be set in ath6kl_connect_ap_mode() once 1145 * The key will be set in ath6kl_connect_ap_mode() once
1119 * the connected event is received from the target. 1146 * the connected event is received from the target.
@@ -1129,8 +1156,8 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1129 * the AP mode has properly started 1156 * the AP mode has properly started
1130 * (ath6kl_install_statioc_wep_keys). 1157 * (ath6kl_install_statioc_wep_keys).
1131 */ 1158 */
1132 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration " 1159 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1133 "until AP mode has been started\n"); 1160 "Delay WEP key configuration until AP mode has been started\n");
1134 vif->wep_key_list[key_index].key_len = key->key_len; 1161 vif->wep_key_list[key_index].key_len = key->key_len;
1135 memcpy(vif->wep_key_list[key_index].key, key->key, 1162 memcpy(vif->wep_key_list[key_index].key, key->key,
1136 key->key_len); 1163 key->key_len);
@@ -1962,8 +1989,7 @@ static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
1962 sizeof(discvr_pattern), discvr_offset, 1989 sizeof(discvr_pattern), discvr_offset,
1963 discvr_pattern, discvr_mask); 1990 discvr_pattern, discvr_mask);
1964 if (ret) { 1991 if (ret) {
1965 ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR " 1992 ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
1966 "pattern\n");
1967 return ret; 1993 return ret;
1968 } 1994 }
1969 } 1995 }
@@ -2031,6 +2057,10 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2031 u8 index = 0; 2057 u8 index = 0;
2032 __be32 ips[MAX_IP_ADDRS]; 2058 __be32 ips[MAX_IP_ADDRS];
2033 2059
2060 /* The FW currently can't support multi-vif WoW properly. */
2061 if (ar->num_vif > 1)
2062 return -EIO;
2063
2034 vif = ath6kl_vif_first(ar); 2064 vif = ath6kl_vif_first(ar);
2035 if (!vif) 2065 if (!vif)
2036 return -EIO; 2066 return -EIO;
@@ -2044,6 +2074,13 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2044 if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) 2074 if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
2045 return -EINVAL; 2075 return -EINVAL;
2046 2076
2077 if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) {
2078 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2079 vif->fw_vif_idx, false);
2080 if (ret)
2081 return ret;
2082 }
2083
2047 /* Clear existing WOW patterns */ 2084 /* Clear existing WOW patterns */
2048 for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++) 2085 for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
2049 ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx, 2086 ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
@@ -2147,8 +2184,8 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
2147 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, 2184 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2148 ATH6KL_HOST_MODE_AWAKE); 2185 ATH6KL_HOST_MODE_AWAKE);
2149 if (ret) { 2186 if (ret) {
2150 ath6kl_warn("Failed to configure host sleep mode for " 2187 ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
2151 "wow resume: %d\n", ret); 2188 ret);
2152 ar->state = ATH6KL_STATE_WOW; 2189 ar->state = ATH6KL_STATE_WOW;
2153 return ret; 2190 return ret;
2154 } 2191 }
@@ -2172,6 +2209,13 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
2172 2209
2173 ar->state = ATH6KL_STATE_ON; 2210 ar->state = ATH6KL_STATE_ON;
2174 2211
2212 if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags)) {
2213 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2214 vif->fw_vif_idx, true);
2215 if (ret)
2216 return ret;
2217 }
2218
2175 netif_wake_queue(vif->ndev); 2219 netif_wake_queue(vif->ndev);
2176 2220
2177 return 0; 2221 return 0;
@@ -2186,8 +2230,10 @@ static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
2186 if (!vif) 2230 if (!vif)
2187 return -EIO; 2231 return -EIO;
2188 2232
2189 if (!ath6kl_cfg80211_ready(vif)) 2233 if (!test_bit(WMI_READY, &ar->flag)) {
2234 ath6kl_err("deepsleep failed as wmi is not ready\n");
2190 return -EIO; 2235 return -EIO;
2236 }
2191 2237
2192 ath6kl_cfg80211_stop_all(ar); 2238 ath6kl_cfg80211_stop_all(ar);
2193 2239
@@ -2447,6 +2493,24 @@ static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band,
2447 band, htcap); 2493 band, htcap);
2448} 2494}
2449 2495
2496static int ath6kl_restore_htcap(struct ath6kl_vif *vif)
2497{
2498 struct wiphy *wiphy = vif->ar->wiphy;
2499 int band, ret = 0;
2500
2501 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2502 if (!wiphy->bands[band])
2503 continue;
2504
2505 ret = ath6kl_set_htcap(vif, band,
2506 wiphy->bands[band]->ht_cap.ht_supported);
2507 if (ret)
2508 return ret;
2509 }
2510
2511 return ret;
2512}
2513
2450static bool ath6kl_is_p2p_ie(const u8 *pos) 2514static bool ath6kl_is_p2p_ie(const u8 *pos)
2451{ 2515{
2452 return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 2516 return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
@@ -2568,28 +2632,34 @@ static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
2568 /* skip element id and length */ 2632 /* skip element id and length */
2569 rsn_ie += 2; 2633 rsn_ie += 2;
2570 2634
2571 /* skip version, group cipher */ 2635 /* skip version */
2572 if (rsn_ie_len < 6) 2636 if (rsn_ie_len < 2)
2573 return -EINVAL; 2637 return -EINVAL;
2574 rsn_ie += 6; 2638 rsn_ie += 2;
2575 rsn_ie_len -= 6; 2639 rsn_ie_len -= 2;
2640
2641 /* skip group cipher suite */
2642 if (rsn_ie_len < 4)
2643 return 0;
2644 rsn_ie += 4;
2645 rsn_ie_len -= 4;
2576 2646
2577 /* skip pairwise cipher suite */ 2647 /* skip pairwise cipher suite */
2578 if (rsn_ie_len < 2) 2648 if (rsn_ie_len < 2)
2579 return -EINVAL; 2649 return 0;
2580 cnt = *((u16 *) rsn_ie); 2650 cnt = get_unaligned_le16(rsn_ie);
2581 rsn_ie += (2 + cnt * 4); 2651 rsn_ie += (2 + cnt * 4);
2582 rsn_ie_len -= (2 + cnt * 4); 2652 rsn_ie_len -= (2 + cnt * 4);
2583 2653
2584 /* skip akm suite */ 2654 /* skip akm suite */
2585 if (rsn_ie_len < 2) 2655 if (rsn_ie_len < 2)
2586 return -EINVAL; 2656 return 0;
2587 cnt = *((u16 *) rsn_ie); 2657 cnt = get_unaligned_le16(rsn_ie);
2588 rsn_ie += (2 + cnt * 4); 2658 rsn_ie += (2 + cnt * 4);
2589 rsn_ie_len -= (2 + cnt * 4); 2659 rsn_ie_len -= (2 + cnt * 4);
2590 2660
2591 if (rsn_ie_len < 2) 2661 if (rsn_ie_len < 2)
2592 return -EINVAL; 2662 return 0;
2593 2663
2594 memcpy(rsn_capab, rsn_ie, 2); 2664 memcpy(rsn_capab, rsn_ie, 2);
2595 2665
@@ -2766,6 +2836,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2766 return res; 2836 return res;
2767 } 2837 }
2768 2838
2839 memcpy(&vif->profile, &p, sizeof(p));
2769 res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p); 2840 res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2770 if (res < 0) 2841 if (res < 0)
2771 return res; 2842 return res;
@@ -2801,13 +2872,7 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
2801 clear_bit(CONNECTED, &vif->flags); 2872 clear_bit(CONNECTED, &vif->flags);
2802 2873
2803 /* Restore ht setting in firmware */ 2874 /* Restore ht setting in firmware */
2804 if (ath6kl_set_htcap(vif, IEEE80211_BAND_2GHZ, true)) 2875 return ath6kl_restore_htcap(vif);
2805 return -EIO;
2806
2807 if (ath6kl_set_htcap(vif, IEEE80211_BAND_5GHZ, true))
2808 return -EIO;
2809
2810 return 0;
2811} 2876}
2812 2877
2813static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 2878static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@@ -3081,7 +3146,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3081 struct ath6kl_vif *vif = netdev_priv(dev); 3146 struct ath6kl_vif *vif = netdev_priv(dev);
3082 u16 interval; 3147 u16 interval;
3083 int ret; 3148 int ret;
3084 u8 i;
3085 3149
3086 if (ar->state != ATH6KL_STATE_ON) 3150 if (ar->state != ATH6KL_STATE_ON)
3087 return -EIO; 3151 return -EIO;
@@ -3089,29 +3153,23 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3089 if (vif->sme_state != SME_DISCONNECTED) 3153 if (vif->sme_state != SME_DISCONNECTED)
3090 return -EBUSY; 3154 return -EBUSY;
3091 3155
3156 /* The FW currently can't support multi-vif WoW properly. */
3157 if (ar->num_vif > 1)
3158 return -EIO;
3159
3092 ath6kl_cfg80211_scan_complete_event(vif, true); 3160 ath6kl_cfg80211_scan_complete_event(vif, true);
3093 3161
3094 for (i = 0; i < ar->wiphy->max_sched_scan_ssids; i++) { 3162 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
3095 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, 3163 request->n_ssids);
3096 i, DISABLE_SSID_FLAG, 3164 if (ret < 0)
3097 0, NULL); 3165 return ret;
3098 }
3099 3166
3100 /* fw uses seconds, also make sure that it's >0 */ 3167 /* fw uses seconds, also make sure that it's >0 */
3101 interval = max_t(u16, 1, request->interval / 1000); 3168 interval = max_t(u16, 1, request->interval / 1000);
3102 3169
3103 ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 3170 ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
3104 interval, interval, 3171 interval, interval,
3105 10, 0, 0, 0, 3, 0, 0, 0); 3172 vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
3106
3107 if (request->n_ssids && request->ssids[0].ssid_len) {
3108 for (i = 0; i < request->n_ssids; i++) {
3109 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
3110 i, SPECIFIC_SSID_FLAG,
3111 request->ssids[i].ssid_len,
3112 request->ssids[i].ssid);
3113 }
3114 }
3115 3173
3116 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, 3174 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
3117 ATH6KL_WOW_MODE_ENABLE, 3175 ATH6KL_WOW_MODE_ENABLE,
@@ -3271,8 +3329,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3271 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; 3329 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3272 3330
3273 if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0) 3331 if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
3274 ath6kl_warn("ath6kl_deep_sleep_enable: " 3332 ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n");
3275 "wmi_powermode_cmd failed\n");
3276 return; 3333 return;
3277 } 3334 }
3278 3335
@@ -3352,6 +3409,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
3352 vif->next_mode = nw_type; 3409 vif->next_mode = nw_type;
3353 vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL; 3410 vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3354 vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME; 3411 vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3412 vif->bg_scan_period = 0;
3355 vif->htcap.ht_enable = true; 3413 vif->htcap.ht_enable = true;
3356 3414
3357 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); 3415 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
@@ -3393,6 +3451,7 @@ err:
3393int ath6kl_cfg80211_init(struct ath6kl *ar) 3451int ath6kl_cfg80211_init(struct ath6kl *ar)
3394{ 3452{
3395 struct wiphy *wiphy = ar->wiphy; 3453 struct wiphy *wiphy = ar->wiphy;
3454 bool band_2gig = false, band_5gig = false, ht = false;
3396 int ret; 3455 int ret;
3397 3456
3398 wiphy->mgmt_stypes = ath6kl_mgmt_stypes; 3457 wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
@@ -3413,8 +3472,46 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3413 /* max num of ssids that can be probed during scanning */ 3472 /* max num of ssids that can be probed during scanning */
3414 wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; 3473 wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
3415 wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ 3474 wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3416 wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; 3475 switch (ar->hw.cap) {
3417 wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; 3476 case WMI_11AN_CAP:
3477 ht = true;
3478 case WMI_11A_CAP:
3479 band_5gig = true;
3480 break;
3481 case WMI_11GN_CAP:
3482 ht = true;
3483 case WMI_11G_CAP:
3484 band_2gig = true;
3485 break;
3486 case WMI_11AGN_CAP:
3487 ht = true;
3488 case WMI_11AG_CAP:
3489 band_2gig = true;
3490 band_5gig = true;
3491 break;
3492 default:
3493 ath6kl_err("invalid phy capability!\n");
3494 return -EINVAL;
3495 }
3496
3497 /*
3498 * Even if the fw has HT support, advertise HT cap only when
3499 * the firmware has support to override RSN capability, otherwise
3500 * 4-way handshake would fail.
3501 */
3502 if (!(ht &&
3503 test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
3504 ar->fw_capabilities))) {
3505 ath6kl_band_2ghz.ht_cap.cap = 0;
3506 ath6kl_band_2ghz.ht_cap.ht_supported = false;
3507 ath6kl_band_5ghz.ht_cap.cap = 0;
3508 ath6kl_band_5ghz.ht_cap.ht_supported = false;
3509 }
3510 if (band_2gig)
3511 wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3512 if (band_5gig)
3513 wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
3514
3418 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 3515 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3419 3516
3420 wiphy->cipher_suites = cipher_suites; 3517 wiphy->cipher_suites = cipher_suites;
@@ -3430,7 +3527,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3430 wiphy->wowlan.pattern_min_len = 1; 3527 wiphy->wowlan.pattern_min_len = 1;
3431 wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; 3528 wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
3432 3529
3433 wiphy->max_sched_scan_ssids = 10; 3530 wiphy->max_sched_scan_ssids = MAX_PROBED_SSID_INDEX;
3434 3531
3435 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | 3532 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3436 WIPHY_FLAG_HAVE_AP_SME | 3533 WIPHY_FLAG_HAVE_AP_SME |
@@ -3447,8 +3544,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3447 ar->wiphy->probe_resp_offload = 3544 ar->wiphy->probe_resp_offload =
3448 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | 3545 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3449 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | 3546 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
3450 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | 3547 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
3451 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
3452 3548
3453 ret = wiphy_register(wiphy); 3549 ret = wiphy_register(wiphy);
3454 if (ret < 0) { 3550 if (ret < 0) {
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
index c5def436417f..5ea8cbb79f43 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.h
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h
@@ -28,6 +28,8 @@ enum ath6kl_cfg_suspend_mode {
28struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, 28struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
29 enum nl80211_iftype type, 29 enum nl80211_iftype type,
30 u8 fw_vif_idx, u8 nw_type); 30 u8 fw_vif_idx, u8 nw_type);
31void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
32 enum wmi_phy_mode mode);
31void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); 33void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted);
32 34
33void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, 35void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 9d67964a51dd..4d9c6f142698 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -126,9 +126,9 @@ struct ath6kl_fw_ie {
126#define AR6003_HW_2_0_FIRMWARE_FILE "athwlan.bin.z77" 126#define AR6003_HW_2_0_FIRMWARE_FILE "athwlan.bin.z77"
127#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" 127#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "athtcmd_ram.bin"
128#define AR6003_HW_2_0_PATCH_FILE "data.patch.bin" 128#define AR6003_HW_2_0_PATCH_FILE "data.patch.bin"
129#define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin" 129#define AR6003_HW_2_0_BOARD_DATA_FILE AR6003_HW_2_0_FW_DIR "/bdata.bin"
130#define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \ 130#define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \
131 "ath6k/AR6003/hw2.0/bdata.SD31.bin" 131 AR6003_HW_2_0_FW_DIR "/bdata.SD31.bin"
132 132
133/* AR6003 3.0 definitions */ 133/* AR6003 3.0 definitions */
134#define AR6003_HW_2_1_1_VERSION 0x30000582 134#define AR6003_HW_2_1_1_VERSION 0x30000582
@@ -139,25 +139,33 @@ struct ath6kl_fw_ie {
139#define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE "utf.bin" 139#define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE "utf.bin"
140#define AR6003_HW_2_1_1_TESTSCRIPT_FILE "nullTestFlow.bin" 140#define AR6003_HW_2_1_1_TESTSCRIPT_FILE "nullTestFlow.bin"
141#define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin" 141#define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin"
142#define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" 142#define AR6003_HW_2_1_1_BOARD_DATA_FILE AR6003_HW_2_1_1_FW_DIR "/bdata.bin"
143#define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \ 143#define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \
144 "ath6k/AR6003/hw2.1.1/bdata.SD31.bin" 144 AR6003_HW_2_1_1_FW_DIR "/bdata.SD31.bin"
145 145
146/* AR6004 1.0 definitions */ 146/* AR6004 1.0 definitions */
147#define AR6004_HW_1_0_VERSION 0x30000623 147#define AR6004_HW_1_0_VERSION 0x30000623
148#define AR6004_HW_1_0_FW_DIR "ath6k/AR6004/hw1.0" 148#define AR6004_HW_1_0_FW_DIR "ath6k/AR6004/hw1.0"
149#define AR6004_HW_1_0_FIRMWARE_FILE "fw.ram.bin" 149#define AR6004_HW_1_0_FIRMWARE_FILE "fw.ram.bin"
150#define AR6004_HW_1_0_BOARD_DATA_FILE "ath6k/AR6004/hw1.0/bdata.bin" 150#define AR6004_HW_1_0_BOARD_DATA_FILE AR6004_HW_1_0_FW_DIR "/bdata.bin"
151#define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \ 151#define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \
152 "ath6k/AR6004/hw1.0/bdata.DB132.bin" 152 AR6004_HW_1_0_FW_DIR "/bdata.DB132.bin"
153 153
154/* AR6004 1.1 definitions */ 154/* AR6004 1.1 definitions */
155#define AR6004_HW_1_1_VERSION 0x30000001 155#define AR6004_HW_1_1_VERSION 0x30000001
156#define AR6004_HW_1_1_FW_DIR "ath6k/AR6004/hw1.1" 156#define AR6004_HW_1_1_FW_DIR "ath6k/AR6004/hw1.1"
157#define AR6004_HW_1_1_FIRMWARE_FILE "fw.ram.bin" 157#define AR6004_HW_1_1_FIRMWARE_FILE "fw.ram.bin"
158#define AR6004_HW_1_1_BOARD_DATA_FILE "ath6k/AR6004/hw1.1/bdata.bin" 158#define AR6004_HW_1_1_BOARD_DATA_FILE AR6004_HW_1_1_FW_DIR "/bdata.bin"
159#define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \ 159#define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \
160 "ath6k/AR6004/hw1.1/bdata.DB132.bin" 160 AR6004_HW_1_1_FW_DIR "/bdata.DB132.bin"
161
162/* AR6004 1.2 definitions */
163#define AR6004_HW_1_2_VERSION 0x300007e8
164#define AR6004_HW_1_2_FW_DIR "ath6k/AR6004/hw1.2"
165#define AR6004_HW_1_2_FIRMWARE_FILE "fw.ram.bin"
166#define AR6004_HW_1_2_BOARD_DATA_FILE AR6004_HW_1_2_FW_DIR "/bdata.bin"
167#define AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE \
168 AR6004_HW_1_2_FW_DIR "/bdata.bin"
161 169
162/* Per STA data, used in AP mode */ 170/* Per STA data, used in AP mode */
163#define STA_PS_AWAKE BIT(0) 171#define STA_PS_AWAKE BIT(0)
@@ -502,6 +510,8 @@ enum ath6kl_vif_state {
502 WLAN_ENABLED, 510 WLAN_ENABLED,
503 STATS_UPDATE_PEND, 511 STATS_UPDATE_PEND,
504 HOST_SLEEP_MODE_CMD_PROCESSED, 512 HOST_SLEEP_MODE_CMD_PROCESSED,
513 NETDEV_MCAST_ALL_ON,
514 NETDEV_MCAST_ALL_OFF,
505}; 515};
506 516
507struct ath6kl_vif { 517struct ath6kl_vif {
@@ -549,9 +559,11 @@ struct ath6kl_vif {
549 u16 assoc_bss_beacon_int; 559 u16 assoc_bss_beacon_int;
550 u16 listen_intvl_t; 560 u16 listen_intvl_t;
551 u16 bmiss_time_t; 561 u16 bmiss_time_t;
562 u16 bg_scan_period;
552 u8 assoc_bss_dtim_period; 563 u8 assoc_bss_dtim_period;
553 struct net_device_stats net_stats; 564 struct net_device_stats net_stats;
554 struct target_stats target_stats; 565 struct target_stats target_stats;
566 struct wmi_connect_cmd profile;
555 567
556 struct list_head mc_filter; 568 struct list_head mc_filter;
557}; 569};
@@ -640,6 +652,7 @@ struct ath6kl {
640 u8 sta_list_index; 652 u8 sta_list_index;
641 struct ath6kl_req_key ap_mode_bkey; 653 struct ath6kl_req_key ap_mode_bkey;
642 struct sk_buff_head mcastpsq; 654 struct sk_buff_head mcastpsq;
655 u32 want_ch_switch;
643 656
644 /* 657 /*
645 * FIXME: protects access to mcastpsq but is actually useless as 658 * FIXME: protects access to mcastpsq but is actually useless as
@@ -672,6 +685,7 @@ struct ath6kl {
672 u32 refclk_hz; 685 u32 refclk_hz;
673 u32 uarttx_pin; 686 u32 uarttx_pin;
674 u32 testscript_addr; 687 u32 testscript_addr;
688 enum wmi_phy_cap cap;
675 689
676 struct ath6kl_hw_fw { 690 struct ath6kl_hw_fw {
677 const char *dir; 691 const char *dir;
@@ -805,7 +819,8 @@ void aggr_reset_state(struct aggr_info_conn *aggr_conn);
805struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr); 819struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr);
806struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); 820struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
807 821
808void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver); 822void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver,
823 enum wmi_phy_cap cap);
809int ath6kl_control_tx(void *devt, struct sk_buff *skb, 824int ath6kl_control_tx(void *devt, struct sk_buff *skb,
810 enum htc_endpoint_id eid); 825 enum htc_endpoint_id eid);
811void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, 826void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel,
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 1b76aff78508..15cfe30e54fd 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -401,8 +401,10 @@ static ssize_t ath6kl_fwlog_block_read(struct file *file,
401 401
402 ret = wait_for_completion_interruptible( 402 ret = wait_for_completion_interruptible(
403 &ar->debug.fwlog_completion); 403 &ar->debug.fwlog_completion);
404 if (ret == -ERESTARTSYS) 404 if (ret == -ERESTARTSYS) {
405 vfree(buf);
405 return ret; 406 return ret;
407 }
406 408
407 spin_lock(&ar->debug.fwlog_queue.lock); 409 spin_lock(&ar->debug.fwlog_queue.lock);
408 } 410 }
@@ -1570,10 +1572,15 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file,
1570 size_t count, loff_t *ppos) 1572 size_t count, loff_t *ppos)
1571{ 1573{
1572 struct ath6kl *ar = file->private_data; 1574 struct ath6kl *ar = file->private_data;
1575 struct ath6kl_vif *vif;
1573 u16 bgscan_int; 1576 u16 bgscan_int;
1574 char buf[32]; 1577 char buf[32];
1575 ssize_t len; 1578 ssize_t len;
1576 1579
1580 vif = ath6kl_vif_first(ar);
1581 if (!vif)
1582 return -EIO;
1583
1577 len = min(count, sizeof(buf) - 1); 1584 len = min(count, sizeof(buf) - 1);
1578 if (copy_from_user(buf, user_buf, len)) 1585 if (copy_from_user(buf, user_buf, len))
1579 return -EFAULT; 1586 return -EFAULT;
@@ -1585,6 +1592,8 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file,
1585 if (bgscan_int == 0) 1592 if (bgscan_int == 0)
1586 bgscan_int = 0xffff; 1593 bgscan_int = 0xffff;
1587 1594
1595 vif->bg_scan_period = bgscan_int;
1596
1588 ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3, 1597 ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3,
1589 0, 0, 0); 1598 0, 0, 0);
1590 1599
@@ -1809,6 +1818,7 @@ int ath6kl_debug_init_fs(struct ath6kl *ar)
1809void ath6kl_debug_cleanup(struct ath6kl *ar) 1818void ath6kl_debug_cleanup(struct ath6kl *ar)
1810{ 1819{
1811 skb_queue_purge(&ar->debug.fwlog_queue); 1820 skb_queue_purge(&ar->debug.fwlog_queue);
1821 complete(&ar->debug.fwlog_completion);
1812 kfree(ar->debug.roam_tbl); 1822 kfree(ar->debug.roam_tbl);
1813} 1823}
1814 1824
diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
index 065e61516d7a..2798624d3a9d 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
@@ -83,10 +83,7 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
83 * never goes inactive EVER. 83 * never goes inactive EVER.
84 */ 84 */
85 cur_ep_dist->dist_flags |= HTC_EP_ACTIVE; 85 cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
86 } else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC) 86 }
87 /* this is the lowest priority data endpoint */
88 /* FIXME: this looks fishy, check */
89 cred_info->lowestpri_ep_dist = cur_ep_dist->list;
90 87
91 /* 88 /*
92 * Streams have to be created (explicit | implicit) for all 89 * Streams have to be created (explicit | implicit) for all
@@ -100,6 +97,13 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
100 */ 97 */
101 } 98 }
102 99
100 /*
101 * For ath6kl_credit_seek function,
102 * it use list_for_each_entry_reverse to walk around the whole ep list.
103 * Therefore assign this lowestpri_ep_dist after walk around the ep_list
104 */
105 cred_info->lowestpri_ep_dist = cur_ep_dist->list;
106
103 WARN_ON(cred_info->cur_free_credits <= 0); 107 WARN_ON(cred_info->cur_free_credits <= 0);
104 108
105 list_for_each_entry(cur_ep_dist, ep_list, list) { 109 list_for_each_entry(cur_ep_dist, ep_list, list) {
@@ -758,7 +762,7 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
758 u32 txb_mask; 762 u32 txb_mask;
759 u8 ac = WMM_NUM_AC; 763 u8 ac = WMM_NUM_AC;
760 764
761 if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || 765 if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) &&
762 (WMI_CONTROL_SVC != endpoint->svc_id)) 766 (WMI_CONTROL_SVC != endpoint->svc_id))
763 ac = target->dev->ar->ep2ac_map[endpoint->eid]; 767 ac = target->dev->ar->ep2ac_map[endpoint->eid];
764 768
@@ -793,16 +797,17 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
793 * itself 797 * itself
794 */ 798 */
795 txb_mask = ((1 << ac) - 1); 799 txb_mask = ((1 << ac) - 1);
796 /* 800
797 * when the scatter request resources drop below a 801 /*
798 * certain threshold, disable Tx bundling for all 802 * when the scatter request resources drop below a
799 * AC's with priority lower than the current requesting 803 * certain threshold, disable Tx bundling for all
800 * AC. Otherwise re-enable Tx bundling for them 804 * AC's with priority lower than the current requesting
801 */ 805 * AC. Otherwise re-enable Tx bundling for them
802 if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS) 806 */
803 target->tx_bndl_mask &= ~txb_mask; 807 if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS)
804 else 808 target->tx_bndl_mask &= ~txb_mask;
805 target->tx_bndl_mask |= txb_mask; 809 else
810 target->tx_bndl_mask |= txb_mask;
806 } 811 }
807 812
808 ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", 813 ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n",
@@ -849,6 +854,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
849 int bundle_sent; 854 int bundle_sent;
850 int n_pkts_bundle; 855 int n_pkts_bundle;
851 u8 ac = WMM_NUM_AC; 856 u8 ac = WMM_NUM_AC;
857 int status;
852 858
853 spin_lock_bh(&target->tx_lock); 859 spin_lock_bh(&target->tx_lock);
854 860
@@ -866,7 +872,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
866 */ 872 */
867 INIT_LIST_HEAD(&txq); 873 INIT_LIST_HEAD(&txq);
868 874
869 if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || 875 if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) &&
870 (WMI_CONTROL_SVC != endpoint->svc_id)) 876 (WMI_CONTROL_SVC != endpoint->svc_id))
871 ac = target->dev->ar->ep2ac_map[endpoint->eid]; 877 ac = target->dev->ar->ep2ac_map[endpoint->eid];
872 878
@@ -910,7 +916,12 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
910 916
911 ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags, 917 ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags,
912 0, packet->info.tx.seqno); 918 0, packet->info.tx.seqno);
913 ath6kl_htc_tx_issue(target, packet); 919 status = ath6kl_htc_tx_issue(target, packet);
920
921 if (status) {
922 packet->status = status;
923 packet->completion(packet->context, packet);
924 }
914 } 925 }
915 926
916 spin_lock_bh(&target->tx_lock); 927 spin_lock_bh(&target->tx_lock);
diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
index b277b3446882..f9626c723693 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
@@ -108,8 +108,6 @@ static void get_htc_packet_credit_based(struct htc_target *target,
108 108
109 /* get packet at head, but don't remove it */ 109 /* get packet at head, but don't remove it */
110 packet = list_first_entry(&ep->txq, struct htc_packet, list); 110 packet = list_first_entry(&ep->txq, struct htc_packet, list);
111 if (packet == NULL)
112 break;
113 111
114 ath6kl_dbg(ATH6KL_DBG_HTC, 112 ath6kl_dbg(ATH6KL_DBG_HTC,
115 "%s: got head packet:0x%p , queue depth: %d\n", 113 "%s: got head packet:0x%p , queue depth: %d\n",
@@ -803,8 +801,6 @@ static int htc_send_packets_multiple(struct htc_target *target,
803 801
804 /* get first packet to find out which ep the packets will go into */ 802 /* get first packet to find out which ep the packets will go into */
805 packet = list_first_entry(pkt_queue, struct htc_packet, list); 803 packet = list_first_entry(pkt_queue, struct htc_packet, list);
806 if (packet == NULL)
807 return -EINVAL;
808 804
809 if (packet->endpoint >= ENDPOINT_MAX) { 805 if (packet->endpoint >= ENDPOINT_MAX) {
810 WARN_ON_ONCE(1); 806 WARN_ON_ONCE(1);
@@ -1382,6 +1378,9 @@ static int ath6kl_htc_pipe_conn_service(struct htc_target *target,
1382 /* copy all the callbacks */ 1378 /* copy all the callbacks */
1383 ep->ep_cb = conn_req->ep_cb; 1379 ep->ep_cb = conn_req->ep_cb;
1384 1380
1381 /* initialize tx_drop_packet_threshold */
1382 ep->tx_drop_packet_threshold = MAX_HI_COOKIE_NUM;
1383
1385 status = ath6kl_hif_pipe_map_service(ar, ep->svc_id, 1384 status = ath6kl_hif_pipe_map_service(ar, ep->svc_id,
1386 &ep->pipe.pipeid_ul, 1385 &ep->pipe.pipeid_ul,
1387 &ep->pipe.pipeid_dl); 1386 &ep->pipe.pipeid_dl);
@@ -1636,10 +1635,6 @@ static int ath6kl_htc_pipe_add_rxbuf_multiple(struct htc_target *target,
1636 return -EINVAL; 1635 return -EINVAL;
1637 1636
1638 first = list_first_entry(pkt_queue, struct htc_packet, list); 1637 first = list_first_entry(pkt_queue, struct htc_packet, list);
1639 if (first == NULL) {
1640 WARN_ON_ONCE(1);
1641 return -EINVAL;
1642 }
1643 1638
1644 if (first->endpoint >= ENDPOINT_MAX) { 1639 if (first->endpoint >= ENDPOINT_MAX) {
1645 WARN_ON_ONCE(1); 1640 WARN_ON_ONCE(1);
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 29ef50ea07d5..7eb0515f458a 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -119,6 +119,24 @@ static const struct ath6kl_hw hw_list[] = {
119 .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE, 119 .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE,
120 .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE, 120 .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE,
121 }, 121 },
122 {
123 .id = AR6004_HW_1_2_VERSION,
124 .name = "ar6004 hw 1.2",
125 .dataset_patch_addr = 0x436ecc,
126 .app_load_addr = 0x1234,
127 .board_ext_data_addr = 0x437000,
128 .reserved_ram_size = 9216,
129 .board_addr = 0x435c00,
130 .refclk_hz = 40000000,
131 .uarttx_pin = 11,
132
133 .fw = {
134 .dir = AR6004_HW_1_2_FW_DIR,
135 .fw = AR6004_HW_1_2_FIRMWARE_FILE,
136 },
137 .fw_board = AR6004_HW_1_2_BOARD_DATA_FILE,
138 .fw_default_board = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE,
139 },
122}; 140};
123 141
124/* 142/*
@@ -445,9 +463,9 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
445 P2P_FLAG_MACADDR_REQ | 463 P2P_FLAG_MACADDR_REQ |
446 P2P_FLAG_HMODEL_REQ); 464 P2P_FLAG_HMODEL_REQ);
447 if (ret) { 465 if (ret) {
448 ath6kl_dbg(ATH6KL_DBG_TRC, "failed to request P2P " 466 ath6kl_dbg(ATH6KL_DBG_TRC,
449 "capabilities (%d) - assuming P2P not " 467 "failed to request P2P capabilities (%d) - assuming P2P not supported\n",
450 "supported\n", ret); 468 ret);
451 ar->p2p = false; 469 ar->p2p = false;
452 } 470 }
453 } 471 }
@@ -456,8 +474,9 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
456 /* Enable Probe Request reporting for P2P */ 474 /* Enable Probe Request reporting for P2P */
457 ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true); 475 ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true);
458 if (ret) { 476 if (ret) {
459 ath6kl_dbg(ATH6KL_DBG_TRC, "failed to enable Probe " 477 ath6kl_dbg(ATH6KL_DBG_TRC,
460 "Request reporting (%d)\n", ret); 478 "failed to enable Probe Request reporting (%d)\n",
479 ret);
461 } 480 }
462 } 481 }
463 482
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 4d818f96c415..e5524470529c 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -421,8 +421,8 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
421 if (!ik->valid) 421 if (!ik->valid)
422 break; 422 break;
423 423
424 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed addkey for " 424 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
425 "the initial group key for AP mode\n"); 425 "Delayed addkey for the initial group key for AP mode\n");
426 memset(key_rsc, 0, sizeof(key_rsc)); 426 memset(key_rsc, 0, sizeof(key_rsc));
427 res = ath6kl_wmi_addkey_cmd( 427 res = ath6kl_wmi_addkey_cmd(
428 ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type, 428 ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type,
@@ -430,12 +430,19 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
430 ik->key, 430 ik->key,
431 KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG); 431 KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG);
432 if (res) { 432 if (res) {
433 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed " 433 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
434 "addkey failed: %d\n", res); 434 "Delayed addkey failed: %d\n", res);
435 } 435 }
436 break; 436 break;
437 } 437 }
438 438
439 if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) {
440 ar->want_ch_switch &= ~(1 << vif->fw_vif_idx);
441 /* we actually don't know the phymode, default to HT20 */
442 ath6kl_cfg80211_ch_switch_notify(vif, channel,
443 WMI_11G_HT20);
444 }
445
439 ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); 446 ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0);
440 set_bit(CONNECTED, &vif->flags); 447 set_bit(CONNECTED, &vif->flags);
441 netif_carrier_on(vif->ndev); 448 netif_carrier_on(vif->ndev);
@@ -541,7 +548,8 @@ void ath6kl_disconnect(struct ath6kl_vif *vif)
541 548
542/* WMI Event handlers */ 549/* WMI Event handlers */
543 550
544void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver) 551void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver,
552 enum wmi_phy_cap cap)
545{ 553{
546 struct ath6kl *ar = devt; 554 struct ath6kl *ar = devt;
547 555
@@ -551,6 +559,7 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
551 559
552 ar->version.wlan_ver = sw_ver; 560 ar->version.wlan_ver = sw_ver;
553 ar->version.abi_ver = abi_ver; 561 ar->version.abi_ver = abi_ver;
562 ar->hw.cap = cap;
554 563
555 snprintf(ar->wiphy->fw_version, 564 snprintf(ar->wiphy->fw_version,
556 sizeof(ar->wiphy->fw_version), 565 sizeof(ar->wiphy->fw_version),
@@ -584,6 +593,45 @@ void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status)
584 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status); 593 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status);
585} 594}
586 595
596static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel)
597{
598
599 struct ath6kl *ar = vif->ar;
600
601 vif->next_chan = channel;
602 vif->profile.ch = cpu_to_le16(channel);
603
604 switch (vif->nw_type) {
605 case AP_NETWORK:
606 return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx,
607 &vif->profile);
608 default:
609 ath6kl_err("won't switch channels nw_type=%d\n", vif->nw_type);
610 return -ENOTSUPP;
611 }
612}
613
614static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel)
615{
616
617 struct ath6kl_vif *vif;
618 int res = 0;
619
620 if (!ar->want_ch_switch)
621 return;
622
623 spin_lock_bh(&ar->list_lock);
624 list_for_each_entry(vif, &ar->vif_list, list) {
625 if (ar->want_ch_switch & (1 << vif->fw_vif_idx))
626 res = ath6kl_commit_ch_switch(vif, channel);
627
628 if (res)
629 ath6kl_err("channel switch failed nw_type %d res %d\n",
630 vif->nw_type, res);
631 }
632 spin_unlock_bh(&ar->list_lock);
633}
634
587void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, 635void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
588 u16 listen_int, u16 beacon_int, 636 u16 listen_int, u16 beacon_int,
589 enum network_type net_type, u8 beacon_ie_len, 637 enum network_type net_type, u8 beacon_ie_len,
@@ -601,9 +649,11 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
601 memcpy(vif->bssid, bssid, sizeof(vif->bssid)); 649 memcpy(vif->bssid, bssid, sizeof(vif->bssid));
602 vif->bss_ch = channel; 650 vif->bss_ch = channel;
603 651
604 if ((vif->nw_type == INFRA_NETWORK)) 652 if ((vif->nw_type == INFRA_NETWORK)) {
605 ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 653 ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
606 vif->listen_intvl_t, 0); 654 vif->listen_intvl_t, 0);
655 ath6kl_check_ch_switch(ar, channel);
656 }
607 657
608 netif_wake_queue(vif->ndev); 658 netif_wake_queue(vif->ndev);
609 659
@@ -926,6 +976,11 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
926 struct ath6kl *ar = vif->ar; 976 struct ath6kl *ar = vif->ar;
927 977
928 if (vif->nw_type == AP_NETWORK) { 978 if (vif->nw_type == AP_NETWORK) {
979 /* disconnect due to other STA vif switching channels */
980 if (reason == BSS_DISCONNECTED &&
981 prot_reason_status == WMI_AP_REASON_STA_ROAM)
982 ar->want_ch_switch |= 1 << vif->fw_vif_idx;
983
929 if (!ath6kl_remove_sta(ar, bssid, prot_reason_status)) 984 if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
930 return; 985 return;
931 986
@@ -1090,7 +1145,7 @@ static int ath6kl_set_features(struct net_device *dev,
1090static void ath6kl_set_multicast_list(struct net_device *ndev) 1145static void ath6kl_set_multicast_list(struct net_device *ndev)
1091{ 1146{
1092 struct ath6kl_vif *vif = netdev_priv(ndev); 1147 struct ath6kl_vif *vif = netdev_priv(ndev);
1093 bool mc_all_on = false, mc_all_off = false; 1148 bool mc_all_on = false;
1094 int mc_count = netdev_mc_count(ndev); 1149 int mc_count = netdev_mc_count(ndev);
1095 struct netdev_hw_addr *ha; 1150 struct netdev_hw_addr *ha;
1096 bool found; 1151 bool found;
@@ -1102,24 +1157,41 @@ static void ath6kl_set_multicast_list(struct net_device *ndev)
1102 !test_bit(WLAN_ENABLED, &vif->flags)) 1157 !test_bit(WLAN_ENABLED, &vif->flags))
1103 return; 1158 return;
1104 1159
1160 /* Enable multicast-all filter. */
1105 mc_all_on = !!(ndev->flags & IFF_PROMISC) || 1161 mc_all_on = !!(ndev->flags & IFF_PROMISC) ||
1106 !!(ndev->flags & IFF_ALLMULTI) || 1162 !!(ndev->flags & IFF_ALLMULTI) ||
1107 !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST); 1163 !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST);
1108 1164
1109 mc_all_off = !(ndev->flags & IFF_MULTICAST) || mc_count == 0; 1165 if (mc_all_on)
1166 set_bit(NETDEV_MCAST_ALL_ON, &vif->flags);
1167 else
1168 clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags);
1169
1170 mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON);
1110 1171
1111 if (mc_all_on || mc_all_off) { 1172 if (!(ndev->flags & IFF_MULTICAST)) {
1112 /* Enable/disable all multicast */ 1173 mc_all_on = false;
1113 ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n", 1174 set_bit(NETDEV_MCAST_ALL_OFF, &vif->flags);
1114 mc_all_on ? "enabling" : "disabling"); 1175 } else {
1115 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, 1176 clear_bit(NETDEV_MCAST_ALL_OFF, &vif->flags);
1177 }
1178
1179 /* Enable/disable "multicast-all" filter*/
1180 ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast-all filter\n",
1181 mc_all_on ? "enabling" : "disabling");
1182
1183 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
1116 mc_all_on); 1184 mc_all_on);
1117 if (ret) 1185 if (ret) {
1118 ath6kl_warn("Failed to %s multicast receive\n", 1186 ath6kl_warn("Failed to %s multicast-all receive\n",
1119 mc_all_on ? "enable" : "disable"); 1187 mc_all_on ? "enable" : "disable");
1120 return; 1188 return;
1121 } 1189 }
1122 1190
1191 if (test_bit(NETDEV_MCAST_ALL_ON, &vif->flags))
1192 return;
1193
1194 /* Keep the driver and firmware mcast list in sync. */
1123 list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) { 1195 list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
1124 found = false; 1196 found = false;
1125 netdev_for_each_mc_addr(ha, ndev) { 1197 netdev_for_each_mc_addr(ha, ndev) {
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 44ea7a742101..05b95405f7b5 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -552,7 +552,7 @@ static int ath6kl_sdio_write_async(struct ath6kl *ar, u32 address, u8 *buffer,
552 552
553 bus_req = ath6kl_sdio_alloc_busreq(ar_sdio); 553 bus_req = ath6kl_sdio_alloc_busreq(ar_sdio);
554 554
555 if (!bus_req) 555 if (WARN_ON_ONCE(!bus_req))
556 return -ENOMEM; 556 return -ENOMEM;
557 557
558 bus_req->address = address; 558 bus_req->address = address;
@@ -915,6 +915,9 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
915 } 915 }
916 916
917cut_pwr: 917cut_pwr:
918 if (func->card && func->card->host)
919 func->card->host->pm_flags &= ~MMC_PM_KEEP_POWER;
920
918 return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL); 921 return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL);
919} 922}
920 923
@@ -985,9 +988,8 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
985 } 988 }
986 989
987 if (status) { 990 if (status) {
988 ath6kl_err("%s: failed to write initial bytes of 0x%x " 991 ath6kl_err("%s: failed to write initial bytes of 0x%x to window reg: 0x%X\n",
989 "to window reg: 0x%X\n", __func__, 992 __func__, addr, reg_addr);
990 addr, reg_addr);
991 return status; 993 return status;
992 } 994 }
993 995
@@ -1076,8 +1078,8 @@ static int ath6kl_sdio_bmi_credits(struct ath6kl *ar)
1076 (u8 *)&ar->bmi.cmd_credits, 4, 1078 (u8 *)&ar->bmi.cmd_credits, 4,
1077 HIF_RD_SYNC_BYTE_INC); 1079 HIF_RD_SYNC_BYTE_INC);
1078 if (ret) { 1080 if (ret) {
1079 ath6kl_err("Unable to decrement the command credit " 1081 ath6kl_err("Unable to decrement the command credit count register: %d\n",
1080 "count register: %d\n", ret); 1082 ret);
1081 return ret; 1083 return ret;
1082 } 1084 }
1083 1085
@@ -1457,3 +1459,6 @@ MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
1457MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE); 1459MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE);
1458MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); 1460MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
1459MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); 1461MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
1462MODULE_FIRMWARE(AR6004_HW_1_2_FW_DIR "/" AR6004_HW_1_2_FIRMWARE_FILE);
1463MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE);
1464MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 82f2f5cb475b..67206aedea6c 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -362,15 +362,11 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
362 skb, skb->data, skb->len); 362 skb, skb->data, skb->len);
363 363
364 /* If target is not associated */ 364 /* If target is not associated */
365 if (!test_bit(CONNECTED, &vif->flags)) { 365 if (!test_bit(CONNECTED, &vif->flags))
366 dev_kfree_skb(skb); 366 goto fail_tx;
367 return 0;
368 }
369 367
370 if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) { 368 if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON))
371 dev_kfree_skb(skb); 369 goto fail_tx;
372 return 0;
373 }
374 370
375 if (!test_bit(WMI_READY, &ar->flag)) 371 if (!test_bit(WMI_READY, &ar->flag))
376 goto fail_tx; 372 goto fail_tx;
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index ec7f1f5fd1ca..dfbbe9e7ff75 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -1037,6 +1037,14 @@ static void ath6kl_usb_stop(struct ath6kl *ar)
1037 hif_stop(ar); 1037 hif_stop(ar);
1038} 1038}
1039 1039
1040static void ath6kl_usb_cleanup_scatter(struct ath6kl *ar)
1041{
1042 /*
1043 * USB doesn't support it. Just return.
1044 */
1045 return;
1046}
1047
1040static const struct ath6kl_hif_ops ath6kl_usb_ops = { 1048static const struct ath6kl_hif_ops ath6kl_usb_ops = {
1041 .diag_read32 = ath6kl_usb_diag_read32, 1049 .diag_read32 = ath6kl_usb_diag_read32,
1042 .diag_write32 = ath6kl_usb_diag_write32, 1050 .diag_write32 = ath6kl_usb_diag_write32,
@@ -1049,6 +1057,7 @@ static const struct ath6kl_hif_ops ath6kl_usb_ops = {
1049 .pipe_get_default = ath6kl_usb_get_default_pipe, 1057 .pipe_get_default = ath6kl_usb_get_default_pipe,
1050 .pipe_map_service = ath6kl_usb_map_service_pipe, 1058 .pipe_map_service = ath6kl_usb_map_service_pipe,
1051 .pipe_get_free_queue_number = ath6kl_usb_get_free_queue_number, 1059 .pipe_get_free_queue_number = ath6kl_usb_get_free_queue_number,
1060 .cleanup_scatter = ath6kl_usb_cleanup_scatter,
1052}; 1061};
1053 1062
1054/* ath6kl usb driver registered functions */ 1063/* ath6kl usb driver registered functions */
@@ -1207,3 +1216,6 @@ MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
1207MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); 1216MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE);
1208MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); 1217MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
1209MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); 1218MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
1219MODULE_FIRMWARE(AR6004_HW_1_2_FIRMWARE_FILE);
1220MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE);
1221MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 7c8a9977faf5..ee8ec2394c2c 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/ip.h> 18#include <linux/ip.h>
19#include <linux/in.h>
19#include "core.h" 20#include "core.h"
20#include "debug.h" 21#include "debug.h"
21#include "testmode.h" 22#include "testmode.h"
@@ -289,6 +290,13 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
289 layer2_priority); 290 layer2_priority);
290 } else 291 } else
291 usr_pri = layer2_priority & 0x7; 292 usr_pri = layer2_priority & 0x7;
293
294 /*
295 * Queue the EAPOL frames in the same WMM_AC_VO queue
296 * as that of management frames.
297 */
298 if (skb->protocol == cpu_to_be16(ETH_P_PAE))
299 usr_pri = WMI_VOICE_USER_PRIORITY;
292 } 300 }
293 301
294 /* 302 /*
@@ -460,8 +468,9 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
460 freq, dur); 468 freq, dur);
461 chan = ieee80211_get_channel(ar->wiphy, freq); 469 chan = ieee80211_get_channel(ar->wiphy, freq);
462 if (!chan) { 470 if (!chan) {
463 ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: Unknown channel " 471 ath6kl_dbg(ATH6KL_DBG_WMI,
464 "(freq=%u)\n", freq); 472 "remain_on_chnl: Unknown channel (freq=%u)\n",
473 freq);
465 return -EINVAL; 474 return -EINVAL;
466 } 475 }
467 id = vif->last_roc_id; 476 id = vif->last_roc_id;
@@ -488,12 +497,14 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi,
488 ev = (struct wmi_cancel_remain_on_chnl_event *) datap; 497 ev = (struct wmi_cancel_remain_on_chnl_event *) datap;
489 freq = le32_to_cpu(ev->freq); 498 freq = le32_to_cpu(ev->freq);
490 dur = le32_to_cpu(ev->duration); 499 dur = le32_to_cpu(ev->duration);
491 ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: freq=%u dur=%u " 500 ath6kl_dbg(ATH6KL_DBG_WMI,
492 "status=%u\n", freq, dur, ev->status); 501 "cancel_remain_on_chnl: freq=%u dur=%u status=%u\n",
502 freq, dur, ev->status);
493 chan = ieee80211_get_channel(ar->wiphy, freq); 503 chan = ieee80211_get_channel(ar->wiphy, freq);
494 if (!chan) { 504 if (!chan) {
495 ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: Unknown " 505 ath6kl_dbg(ATH6KL_DBG_WMI,
496 "channel (freq=%u)\n", freq); 506 "cancel_remain_on_chnl: Unknown channel (freq=%u)\n",
507 freq);
497 return -EINVAL; 508 return -EINVAL;
498 } 509 }
499 if (vif->last_cancel_roc_id && 510 if (vif->last_cancel_roc_id &&
@@ -548,12 +559,12 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len,
548 freq = le32_to_cpu(ev->freq); 559 freq = le32_to_cpu(ev->freq);
549 dlen = le16_to_cpu(ev->len); 560 dlen = le16_to_cpu(ev->len);
550 if (datap + len < ev->data + dlen) { 561 if (datap + len < ev->data + dlen) {
551 ath6kl_err("invalid wmi_p2p_rx_probe_req_event: " 562 ath6kl_err("invalid wmi_p2p_rx_probe_req_event: len=%d dlen=%u\n",
552 "len=%d dlen=%u\n", len, dlen); 563 len, dlen);
553 return -EINVAL; 564 return -EINVAL;
554 } 565 }
555 ath6kl_dbg(ATH6KL_DBG_WMI, "rx_probe_req: len=%u freq=%u " 566 ath6kl_dbg(ATH6KL_DBG_WMI,
556 "probe_req_report=%d\n", 567 "rx_probe_req: len=%u freq=%u probe_req_report=%d\n",
557 dlen, freq, vif->probe_req_report); 568 dlen, freq, vif->probe_req_report);
558 569
559 if (vif->probe_req_report || vif->nw_type == AP_NETWORK) 570 if (vif->probe_req_report || vif->nw_type == AP_NETWORK)
@@ -592,8 +603,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len,
592 freq = le32_to_cpu(ev->freq); 603 freq = le32_to_cpu(ev->freq);
593 dlen = le16_to_cpu(ev->len); 604 dlen = le16_to_cpu(ev->len);
594 if (datap + len < ev->data + dlen) { 605 if (datap + len < ev->data + dlen) {
595 ath6kl_err("invalid wmi_rx_action_event: " 606 ath6kl_err("invalid wmi_rx_action_event: len=%d dlen=%u\n",
596 "len=%d dlen=%u\n", len, dlen); 607 len, dlen);
597 return -EINVAL; 608 return -EINVAL;
598 } 609 }
599 ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); 610 ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
@@ -687,7 +698,7 @@ static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len)
687 698
688 ath6kl_ready_event(wmi->parent_dev, ev->mac_addr, 699 ath6kl_ready_event(wmi->parent_dev, ev->mac_addr,
689 le32_to_cpu(ev->sw_version), 700 le32_to_cpu(ev->sw_version),
690 le32_to_cpu(ev->abi_version)); 701 le32_to_cpu(ev->abi_version), ev->phy_cap);
691 702
692 return 0; 703 return 0;
693} 704}
@@ -777,16 +788,15 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,
777 /* AP mode start/STA connected event */ 788 /* AP mode start/STA connected event */
778 struct net_device *dev = vif->ndev; 789 struct net_device *dev = vif->ndev;
779 if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) { 790 if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) {
780 ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM " 791 ath6kl_dbg(ATH6KL_DBG_WMI,
781 "(AP started)\n", 792 "%s: freq %d bssid %pM (AP started)\n",
782 __func__, le16_to_cpu(ev->u.ap_bss.ch), 793 __func__, le16_to_cpu(ev->u.ap_bss.ch),
783 ev->u.ap_bss.bssid); 794 ev->u.ap_bss.bssid);
784 ath6kl_connect_ap_mode_bss( 795 ath6kl_connect_ap_mode_bss(
785 vif, le16_to_cpu(ev->u.ap_bss.ch)); 796 vif, le16_to_cpu(ev->u.ap_bss.ch));
786 } else { 797 } else {
787 ath6kl_dbg(ATH6KL_DBG_WMI, "%s: aid %u mac_addr %pM " 798 ath6kl_dbg(ATH6KL_DBG_WMI,
788 "auth=%u keymgmt=%u cipher=%u apsd_info=%u " 799 "%s: aid %u mac_addr %pM auth=%u keymgmt=%u cipher=%u apsd_info=%u (STA connected)\n",
789 "(STA connected)\n",
790 __func__, ev->u.ap_sta.aid, 800 __func__, ev->u.ap_sta.aid,
791 ev->u.ap_sta.mac_addr, 801 ev->u.ap_sta.mac_addr,
792 ev->u.ap_sta.auth, 802 ev->u.ap_sta.auth,
@@ -1229,8 +1239,9 @@ static int ath6kl_wmi_neighbor_report_event_rx(struct wmi *wmi, u8 *datap,
1229 ev = (struct wmi_neighbor_report_event *) datap; 1239 ev = (struct wmi_neighbor_report_event *) datap;
1230 if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info) 1240 if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info)
1231 > len) { 1241 > len) {
1232 ath6kl_dbg(ATH6KL_DBG_WMI, "truncated neighbor event " 1242 ath6kl_dbg(ATH6KL_DBG_WMI,
1233 "(num=%d len=%d)\n", ev->num_neighbors, len); 1243 "truncated neighbor event (num=%d len=%d)\n",
1244 ev->num_neighbors, len);
1234 return -EINVAL; 1245 return -EINVAL;
1235 } 1246 }
1236 for (i = 0; i < ev->num_neighbors; i++) { 1247 for (i = 0; i < ev->num_neighbors; i++) {
@@ -1814,12 +1825,14 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
1814 u32 home_dwell_time, u32 force_scan_interval, 1825 u32 home_dwell_time, u32 force_scan_interval,
1815 s8 num_chan, u16 *ch_list, u32 no_cck, u32 *rates) 1826 s8 num_chan, u16 *ch_list, u32 no_cck, u32 *rates)
1816{ 1827{
1828 struct ieee80211_supported_band *sband;
1817 struct sk_buff *skb; 1829 struct sk_buff *skb;
1818 struct wmi_begin_scan_cmd *sc; 1830 struct wmi_begin_scan_cmd *sc;
1819 s8 size; 1831 s8 size, *supp_rates;
1820 int i, band, ret; 1832 int i, band, ret;
1821 struct ath6kl *ar = wmi->parent_dev; 1833 struct ath6kl *ar = wmi->parent_dev;
1822 int num_rates; 1834 int num_rates;
1835 u32 ratemask;
1823 1836
1824 size = sizeof(struct wmi_begin_scan_cmd); 1837 size = sizeof(struct wmi_begin_scan_cmd);
1825 1838
@@ -1846,10 +1859,13 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
1846 sc->num_ch = num_chan; 1859 sc->num_ch = num_chan;
1847 1860
1848 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1861 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1849 struct ieee80211_supported_band *sband = 1862 sband = ar->wiphy->bands[band];
1850 ar->wiphy->bands[band]; 1863
1851 u32 ratemask = rates[band]; 1864 if (!sband)
1852 u8 *supp_rates = sc->supp_rates[band].rates; 1865 continue;
1866
1867 ratemask = rates[band];
1868 supp_rates = sc->supp_rates[band].rates;
1853 num_rates = 0; 1869 num_rates = 0;
1854 1870
1855 for (i = 0; i < sband->n_bitrates; i++) { 1871 for (i = 0; i < sband->n_bitrates; i++) {
@@ -2129,8 +2145,8 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index,
2129 struct wmi_add_cipher_key_cmd *cmd; 2145 struct wmi_add_cipher_key_cmd *cmd;
2130 int ret; 2146 int ret;
2131 2147
2132 ath6kl_dbg(ATH6KL_DBG_WMI, "addkey cmd: key_index=%u key_type=%d " 2148 ath6kl_dbg(ATH6KL_DBG_WMI,
2133 "key_usage=%d key_len=%d key_op_ctrl=%d\n", 2149 "addkey cmd: key_index=%u key_type=%d key_usage=%d key_len=%d key_op_ctrl=%d\n",
2134 key_index, key_type, key_usage, key_len, key_op_ctrl); 2150 key_index, key_type, key_usage, key_len, key_op_ctrl);
2135 2151
2136 if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) || 2152 if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) ||
@@ -3047,8 +3063,8 @@ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx,
3047 3063
3048 res = ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_CONFIG_COMMIT_CMDID, 3064 res = ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_CONFIG_COMMIT_CMDID,
3049 NO_SYNC_WMIFLAG); 3065 NO_SYNC_WMIFLAG);
3050 ath6kl_dbg(ATH6KL_DBG_WMI, "%s: nw_type=%u auth_mode=%u ch=%u " 3066 ath6kl_dbg(ATH6KL_DBG_WMI,
3051 "ctrl_flags=0x%x-> res=%d\n", 3067 "%s: nw_type=%u auth_mode=%u ch=%u ctrl_flags=0x%x-> res=%d\n",
3052 __func__, p->nw_type, p->auth_mode, le16_to_cpu(p->ch), 3068 __func__, p->nw_type, p->auth_mode, le16_to_cpu(p->ch),
3053 le32_to_cpu(p->ctrl_flags), res); 3069 le32_to_cpu(p->ctrl_flags), res);
3054 return res; 3070 return res;
@@ -3208,8 +3224,9 @@ int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
3208 if (!skb) 3224 if (!skb)
3209 return -ENOMEM; 3225 return -ENOMEM;
3210 3226
3211 ath6kl_dbg(ATH6KL_DBG_WMI, "set_appie_cmd: mgmt_frm_type=%u " 3227 ath6kl_dbg(ATH6KL_DBG_WMI,
3212 "ie_len=%u\n", mgmt_frm_type, ie_len); 3228 "set_appie_cmd: mgmt_frm_type=%u ie_len=%u\n",
3229 mgmt_frm_type, ie_len);
3213 p = (struct wmi_set_appie_cmd *) skb->data; 3230 p = (struct wmi_set_appie_cmd *) skb->data;
3214 p->mgmt_frm_type = mgmt_frm_type; 3231 p->mgmt_frm_type = mgmt_frm_type;
3215 p->ie_len = ie_len; 3232 p->ie_len = ie_len;
@@ -3310,8 +3327,9 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id,
3310 wmi->last_mgmt_tx_frame = buf; 3327 wmi->last_mgmt_tx_frame = buf;
3311 wmi->last_mgmt_tx_frame_len = data_len; 3328 wmi->last_mgmt_tx_frame_len = data_len;
3312 3329
3313 ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u " 3330 ath6kl_dbg(ATH6KL_DBG_WMI,
3314 "len=%u\n", id, freq, wait, data_len); 3331 "send_action_cmd: id=%u freq=%u wait=%u len=%u\n",
3332 id, freq, wait, data_len);
3315 p = (struct wmi_send_action_cmd *) skb->data; 3333 p = (struct wmi_send_action_cmd *) skb->data;
3316 p->id = cpu_to_le32(id); 3334 p->id = cpu_to_le32(id);
3317 p->freq = cpu_to_le32(freq); 3335 p->freq = cpu_to_le32(freq);
@@ -3348,8 +3366,9 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
3348 wmi->last_mgmt_tx_frame = buf; 3366 wmi->last_mgmt_tx_frame = buf;
3349 wmi->last_mgmt_tx_frame_len = data_len; 3367 wmi->last_mgmt_tx_frame_len = data_len;
3350 3368
3351 ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u " 3369 ath6kl_dbg(ATH6KL_DBG_WMI,
3352 "len=%u\n", id, freq, wait, data_len); 3370 "send_action_cmd: id=%u freq=%u wait=%u len=%u\n",
3371 id, freq, wait, data_len);
3353 p = (struct wmi_send_mgmt_cmd *) skb->data; 3372 p = (struct wmi_send_mgmt_cmd *) skb->data;
3354 p->id = cpu_to_le32(id); 3373 p->id = cpu_to_le32(id);
3355 p->freq = cpu_to_le32(freq); 3374 p->freq = cpu_to_le32(freq);
@@ -3402,8 +3421,9 @@ int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
3402 if (!skb) 3421 if (!skb)
3403 return -ENOMEM; 3422 return -ENOMEM;
3404 3423
3405 ath6kl_dbg(ATH6KL_DBG_WMI, "send_probe_response_cmd: freq=%u dst=%pM " 3424 ath6kl_dbg(ATH6KL_DBG_WMI,
3406 "len=%u\n", freq, dst, data_len); 3425 "send_probe_response_cmd: freq=%u dst=%pM len=%u\n",
3426 freq, dst, data_len);
3407 p = (struct wmi_p2p_probe_response_cmd *) skb->data; 3427 p = (struct wmi_p2p_probe_response_cmd *) skb->data;
3408 p->freq = cpu_to_le32(freq); 3428 p->freq = cpu_to_le32(freq);
3409 memcpy(p->destination_addr, dst, ETH_ALEN); 3429 memcpy(p->destination_addr, dst, ETH_ALEN);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index d3d2ab5c1689..9076bec3a2ba 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -106,6 +106,8 @@ struct wmi_data_sync_bufs {
106#define WMM_AC_VI 2 /* video */ 106#define WMM_AC_VI 2 /* video */
107#define WMM_AC_VO 3 /* voice */ 107#define WMM_AC_VO 3 /* voice */
108 108
109#define WMI_VOICE_USER_PRIORITY 0x7
110
109struct wmi { 111struct wmi {
110 u16 stream_exist_for_ac[WMM_NUM_AC]; 112 u16 stream_exist_for_ac[WMM_NUM_AC];
111 u8 fat_pipe_exist; 113 u8 fat_pipe_exist;
@@ -1151,6 +1153,7 @@ enum wmi_phy_mode {
1151 WMI_11AG_MODE = 0x3, 1153 WMI_11AG_MODE = 0x3,
1152 WMI_11B_MODE = 0x4, 1154 WMI_11B_MODE = 0x4,
1153 WMI_11GONLY_MODE = 0x5, 1155 WMI_11GONLY_MODE = 0x5,
1156 WMI_11G_HT20 = 0x6,
1154}; 1157};
1155 1158
1156#define WMI_MAX_CHANNELS 32 1159#define WMI_MAX_CHANNELS 32
@@ -1416,6 +1419,16 @@ struct wmi_ready_event_2 {
1416 u8 phy_cap; 1419 u8 phy_cap;
1417} __packed; 1420} __packed;
1418 1421
1422/* WMI_PHY_CAPABILITY */
1423enum wmi_phy_cap {
1424 WMI_11A_CAP = 0x01,
1425 WMI_11G_CAP = 0x02,
1426 WMI_11AG_CAP = 0x03,
1427 WMI_11AN_CAP = 0x04,
1428 WMI_11GN_CAP = 0x05,
1429 WMI_11AGN_CAP = 0x06,
1430};
1431
1419/* Connect Event */ 1432/* Connect Event */
1420struct wmi_connect_event { 1433struct wmi_connect_event {
1421 union { 1434 union {
@@ -1468,6 +1481,17 @@ enum wmi_disconnect_reason {
1468 IBSS_MERGE = 0xe, 1481 IBSS_MERGE = 0xe,
1469}; 1482};
1470 1483
1484/* AP mode disconnect proto_reasons */
1485enum ap_disconnect_reason {
1486 WMI_AP_REASON_STA_LEFT = 101,
1487 WMI_AP_REASON_FROM_HOST = 102,
1488 WMI_AP_REASON_COMM_TIMEOUT = 103,
1489 WMI_AP_REASON_MAX_STA = 104,
1490 WMI_AP_REASON_ACL = 105,
1491 WMI_AP_REASON_STA_ROAM = 106,
1492 WMI_AP_REASON_DFS_CHANNEL = 107,
1493};
1494
1471#define ATH6KL_COUNTRY_RD_SHIFT 16 1495#define ATH6KL_COUNTRY_RD_SHIFT 16
1472 1496
1473struct ath6kl_wmi_regdomain { 1497struct ath6kl_wmi_regdomain {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index a0387a027db0..9fdd70fcaf5b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -892,34 +892,6 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
892 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); 892 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
893} 893}
894 894
895static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
896{
897 struct ath9k_rtt_hist *hist;
898 u32 *table;
899 int i;
900 bool restore;
901
902 if (!ah->caldata)
903 return false;
904
905 hist = &ah->caldata->rtt_hist;
906 if (!hist->num_readings)
907 return false;
908
909 ar9003_hw_rtt_enable(ah);
910 ar9003_hw_rtt_set_mask(ah, 0x00);
911 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
912 if (!(ah->rxchainmask & (1 << i)))
913 continue;
914 table = &hist->table[i][hist->num_readings][0];
915 ar9003_hw_rtt_load_hist(ah, i, table);
916 }
917 restore = ar9003_hw_rtt_force_restore(ah);
918 ar9003_hw_rtt_disable(ah);
919
920 return restore;
921}
922
923static bool ar9003_hw_init_cal(struct ath_hw *ah, 895static bool ar9003_hw_init_cal(struct ath_hw *ah,
924 struct ath9k_channel *chan) 896 struct ath9k_channel *chan)
925{ 897{
@@ -942,9 +914,10 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
942 if (!ar9003_hw_rtt_restore(ah, chan)) 914 if (!ar9003_hw_rtt_restore(ah, chan))
943 run_rtt_cal = true; 915 run_rtt_cal = true;
944 916
945 ath_dbg(common, CALIBRATE, "RTT restore %s\n", 917 if (run_rtt_cal)
946 run_rtt_cal ? "failed" : "succeed"); 918 ath_dbg(common, CALIBRATE, "RTT calibration to be done\n");
947 } 919 }
920
948 run_agc_cal = run_rtt_cal; 921 run_agc_cal = run_rtt_cal;
949 922
950 if (run_rtt_cal) { 923 if (run_rtt_cal) {
@@ -1069,17 +1042,14 @@ skip_tx_iqcal:
1069#undef CL_TAB_ENTRY 1042#undef CL_TAB_ENTRY
1070 1043
1071 if (run_rtt_cal && caldata) { 1044 if (run_rtt_cal && caldata) {
1072 struct ath9k_rtt_hist *hist = &caldata->rtt_hist; 1045 if (is_reusable) {
1073 if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) { 1046 if (!ath9k_hw_rfbus_req(ah))
1074 u32 *table; 1047 ath_err(ath9k_hw_common(ah),
1048 "Could not stop baseband\n");
1049 else
1050 ar9003_hw_rtt_fill_hist(ah);
1075 1051
1076 hist->num_readings++; 1052 ath9k_hw_rfbus_done(ah);
1077 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1078 if (!(ah->rxchainmask & (1 << i)))
1079 continue;
1080 table = &hist->table[i][hist->num_readings][0];
1081 ar9003_hw_rtt_fill_hist(ah, i, table);
1082 }
1083 } 1053 }
1084 1054
1085 ar9003_hw_rtt_disable(ah); 1055 ar9003_hw_rtt_disable(ah);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
index 3cac293a2849..ffbb180f91e1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c
+++ b/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,
756 if (caldata) { 756 if (caldata) {
757 caldata->done_txiqcal_once = false; 757 caldata->done_txiqcal_once = false;
758 caldata->done_txclcal_once = false; 758 caldata->done_txclcal_once = false;
759 caldata->rtt_hist.num_readings = 0; 759 caldata->rtt_done = false;
760 } 760 }
761 761
762 if (!ath9k_hw_init_cal(ah, chan)) 762 if (!ath9k_hw_init_cal(ah, chan))
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
index 458bedf0b0ae..74de3539c2c8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include "hw.h" 17#include "hw.h"
18#include "hw-ops.h"
18#include "ar9003_phy.h" 19#include "ar9003_phy.h"
19#include "ar9003_rtt.h" 20#include "ar9003_rtt.h"
20 21
@@ -69,7 +70,7 @@ bool ar9003_hw_rtt_force_restore(struct ath_hw *ah)
69} 70}
70 71
71static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain, 72static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
72 u32 index, u32 data28) 73 u32 index, u32 data28)
73{ 74{
74 u32 val; 75 u32 val;
75 76
@@ -100,12 +101,21 @@ static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
100 RTT_ACCESS_TIMEOUT); 101 RTT_ACCESS_TIMEOUT);
101} 102}
102 103
103void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table) 104void ar9003_hw_rtt_load_hist(struct ath_hw *ah)
104{ 105{
105 int i; 106 int chain, i;
106 107
107 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) 108 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
108 ar9003_hw_rtt_load_hist_entry(ah, chain, i, table[i]); 109 if (!(ah->rxchainmask & (1 << chain)))
110 continue;
111 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
112 ar9003_hw_rtt_load_hist_entry(ah, chain, i,
113 ah->caldata->rtt_table[chain][i]);
114 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
115 "Load RTT value at idx %d, chain %d: 0x%x\n",
116 i, chain, ah->caldata->rtt_table[chain][i]);
117 }
118 }
109} 119}
110 120
111static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index) 121static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
@@ -128,27 +138,71 @@ static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
128 RTT_ACCESS_TIMEOUT)) 138 RTT_ACCESS_TIMEOUT))
129 return RTT_BAD_VALUE; 139 return RTT_BAD_VALUE;
130 140
131 val = REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)); 141 val = MS(REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)),
142 AR_PHY_RTT_SW_RTT_TABLE_DATA);
143
132 144
133 return val; 145 return val;
134} 146}
135 147
136void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table) 148void ar9003_hw_rtt_fill_hist(struct ath_hw *ah)
137{ 149{
138 int i; 150 int chain, i;
151
152 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
153 if (!(ah->rxchainmask & (1 << chain)))
154 continue;
155 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
156 ah->caldata->rtt_table[chain][i] =
157 ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
158 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
159 "RTT value at idx %d, chain %d is: 0x%x\n",
160 i, chain, ah->caldata->rtt_table[chain][i]);
161 }
162 }
139 163
140 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) 164 ah->caldata->rtt_done = true;
141 table[i] = ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
142} 165}
143 166
144void ar9003_hw_rtt_clear_hist(struct ath_hw *ah) 167void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
145{ 168{
146 int i, j; 169 int chain, i;
147 170
148 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 171 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
149 if (!(ah->rxchainmask & (1 << i))) 172 if (!(ah->rxchainmask & (1 << chain)))
150 continue; 173 continue;
151 for (j = 0; j < MAX_RTT_TABLE_ENTRY; j++) 174 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
152 ar9003_hw_rtt_load_hist_entry(ah, i, j, 0); 175 ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0);
153 } 176 }
177
178 if (ah->caldata)
179 ah->caldata->rtt_done = false;
180}
181
182bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
183{
184 bool restore;
185
186 if (!ah->caldata)
187 return false;
188
189 if (!ah->caldata->rtt_done)
190 return false;
191
192 ar9003_hw_rtt_enable(ah);
193 ar9003_hw_rtt_set_mask(ah, 0x10);
194
195 if (!ath9k_hw_rfbus_req(ah)) {
196 ath_err(ath9k_hw_common(ah), "Could not stop baseband\n");
197 restore = false;
198 goto fail;
199 }
200
201 ar9003_hw_rtt_load_hist(ah);
202 restore = ar9003_hw_rtt_force_restore(ah);
203
204fail:
205 ath9k_hw_rfbus_done(ah);
206 ar9003_hw_rtt_disable(ah);
207 return restore;
154} 208}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
index 030758d087d6..a43b30d723a4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
@@ -21,8 +21,9 @@ void ar9003_hw_rtt_enable(struct ath_hw *ah);
21void ar9003_hw_rtt_disable(struct ath_hw *ah); 21void ar9003_hw_rtt_disable(struct ath_hw *ah);
22void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask); 22void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask);
23bool ar9003_hw_rtt_force_restore(struct ath_hw *ah); 23bool ar9003_hw_rtt_force_restore(struct ath_hw *ah);
24void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table); 24void ar9003_hw_rtt_load_hist(struct ath_hw *ah);
25void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table); 25void ar9003_hw_rtt_fill_hist(struct ath_hw *ah);
26void ar9003_hw_rtt_clear_hist(struct ath_hw *ah); 26void ar9003_hw_rtt_clear_hist(struct ath_hw *ah);
27bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan);
27 28
28#endif 29#endif
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f84477c5ebb1..abe05ec85d50 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/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)
1702 * For AR9462, make sure that calibration data for 1702 * For AR9462, make sure that calibration data for
1703 * re-using are present. 1703 * re-using are present.
1704 */ 1704 */
1705 if (AR_SREV_9462(ah) && (!ah->caldata || 1705 if (AR_SREV_9462(ah) && (ah->caldata &&
1706 !ah->caldata->done_txiqcal_once || 1706 (!ah->caldata->done_txiqcal_once ||
1707 !ah->caldata->done_txclcal_once || 1707 !ah->caldata->done_txclcal_once ||
1708 !ah->caldata->rtt_hist.num_readings)) 1708 !ah->caldata->rtt_done)))
1709 goto fail; 1709 goto fail;
1710 1710
1711 ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", 1711 ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n",
@@ -1941,7 +1941,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1941 if (caldata) { 1941 if (caldata) {
1942 caldata->done_txiqcal_once = false; 1942 caldata->done_txiqcal_once = false;
1943 caldata->done_txclcal_once = false; 1943 caldata->done_txclcal_once = false;
1944 caldata->rtt_hist.num_readings = 0;
1945 } 1944 }
1946 if (!ath9k_hw_init_cal(ah, chan)) 1945 if (!ath9k_hw_init_cal(ah, chan))
1947 return -EIO; 1946 return -EIO;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 828b9bbc456d..b620c557c2a6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -348,12 +348,6 @@ enum ath9k_int {
348 CHANNEL_HT40MINUS) 348 CHANNEL_HT40MINUS)
349 349
350#define MAX_RTT_TABLE_ENTRY 6 350#define MAX_RTT_TABLE_ENTRY 6
351#define RTT_HIST_MAX 3
352struct ath9k_rtt_hist {
353 u32 table[AR9300_MAX_CHAINS][RTT_HIST_MAX][MAX_RTT_TABLE_ENTRY];
354 u8 num_readings;
355};
356
357#define MAX_IQCAL_MEASUREMENT 8 351#define MAX_IQCAL_MEASUREMENT 8
358#define MAX_CL_TAB_ENTRY 16 352#define MAX_CL_TAB_ENTRY 16
359 353
@@ -363,6 +357,7 @@ struct ath9k_hw_cal_data {
363 int32_t CalValid; 357 int32_t CalValid;
364 int8_t iCoff; 358 int8_t iCoff;
365 int8_t qCoff; 359 int8_t qCoff;
360 bool rtt_done;
366 bool paprd_done; 361 bool paprd_done;
367 bool nfcal_pending; 362 bool nfcal_pending;
368 bool nfcal_interference; 363 bool nfcal_interference;
@@ -373,8 +368,8 @@ struct ath9k_hw_cal_data {
373 u32 num_measures[AR9300_MAX_CHAINS]; 368 u32 num_measures[AR9300_MAX_CHAINS];
374 int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS]; 369 int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS];
375 u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY]; 370 u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY];
371 u32 rtt_table[AR9300_MAX_CHAINS][MAX_RTT_TABLE_ENTRY];
376 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; 372 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
377 struct ath9k_rtt_hist rtt_hist;
378}; 373};
379 374
380struct ath9k_channel { 375struct ath9k_channel {
diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c
index 424692df239d..565fdbdd6915 100644
--- a/drivers/net/wireless/b43/bus.c
+++ b/drivers/net/wireless/b43/bus.c
@@ -107,11 +107,9 @@ struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core)
107 dev->dma_dev = core->dma_dev; 107 dev->dma_dev = core->dma_dev;
108 dev->irq = core->irq; 108 dev->irq = core->irq;
109 109
110 /*
111 dev->board_vendor = core->bus->boardinfo.vendor; 110 dev->board_vendor = core->bus->boardinfo.vendor;
112 dev->board_type = core->bus->boardinfo.type; 111 dev->board_type = core->bus->boardinfo.type;
113 dev->board_rev = core->bus->boardinfo.rev; 112 dev->board_rev = core->bus->sprom.board_rev;
114 */
115 113
116 dev->chip_id = core->bus->chipinfo.id; 114 dev->chip_id = core->bus->chipinfo.id;
117 dev->chip_rev = core->bus->chipinfo.rev; 115 dev->chip_rev = core->bus->chipinfo.rev;
@@ -210,7 +208,7 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev)
210 208
211 dev->board_vendor = sdev->bus->boardinfo.vendor; 209 dev->board_vendor = sdev->bus->boardinfo.vendor;
212 dev->board_type = sdev->bus->boardinfo.type; 210 dev->board_type = sdev->bus->boardinfo.type;
213 dev->board_rev = sdev->bus->boardinfo.rev; 211 dev->board_rev = sdev->bus->sprom.board_rev;
214 212
215 dev->chip_id = sdev->bus->chip_id; 213 dev->chip_id = sdev->bus->chip_id;
216 dev->chip_rev = sdev->bus->chip_rev; 214 dev->chip_rev = sdev->bus->chip_rev;
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index b5f1b91002bb..777cd74921d7 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1109,7 +1109,7 @@ static bool b43_dma_translation_in_low_word(struct b43_wldev *dev,
1109#ifdef CONFIG_B43_SSB 1109#ifdef CONFIG_B43_SSB
1110 if (dev->dev->bus_type == B43_BUS_SSB && 1110 if (dev->dev->bus_type == B43_BUS_SSB &&
1111 dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && 1111 dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
1112 !(dev->dev->sdev->bus->host_pci->is_pcie && 1112 !(pci_is_pcie(dev->dev->sdev->bus->host_pci) &&
1113 ssb_read32(dev->dev->sdev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64)) 1113 ssb_read32(dev->dev->sdev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64))
1114 return 1; 1114 return 1;
1115#endif 1115#endif
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 617afc8211b2..5a39b226b2e3 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -5243,10 +5243,10 @@ static void b43_sprom_fixup(struct ssb_bus *bus)
5243 5243
5244 /* boardflags workarounds */ 5244 /* boardflags workarounds */
5245 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_DELL && 5245 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_DELL &&
5246 bus->chip_id == 0x4301 && bus->boardinfo.rev == 0x74) 5246 bus->chip_id == 0x4301 && bus->sprom.board_rev == 0x74)
5247 bus->sprom.boardflags_lo |= B43_BFL_BTCOEXIST; 5247 bus->sprom.boardflags_lo |= B43_BFL_BTCOEXIST;
5248 if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && 5248 if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
5249 bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40) 5249 bus->boardinfo.type == 0x4E && bus->sprom.board_rev > 0x40)
5250 bus->sprom.boardflags_lo |= B43_BFL_PACTRL; 5250 bus->sprom.boardflags_lo |= B43_BFL_PACTRL;
5251 if (bus->bustype == SSB_BUSTYPE_PCI) { 5251 if (bus->bustype == SSB_BUSTYPE_PCI) {
5252 pdev = bus->host_pci; 5252 pdev = bus->host_pci;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 1be214b815fb..cd9c9bc186d9 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -1573,8 +1573,6 @@ static void b43legacy_request_firmware(struct work_struct *work)
1573 const char *filename; 1573 const char *filename;
1574 int err; 1574 int err;
1575 1575
1576 /* do dummy read */
1577 ssb_read32(dev->dev, SSB_TMSHIGH);
1578 if (!fw->ucode) { 1576 if (!fw->ucode) {
1579 if (rev == 2) 1577 if (rev == 2)
1580 filename = "ucode2"; 1578 filename = "ucode2";
@@ -3781,7 +3779,7 @@ static void b43legacy_sprom_fixup(struct ssb_bus *bus)
3781 /* boardflags workarounds */ 3779 /* boardflags workarounds */
3782 if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && 3780 if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
3783 bus->boardinfo.type == 0x4E && 3781 bus->boardinfo.type == 0x4E &&
3784 bus->boardinfo.rev > 0x40) 3782 bus->sprom.board_rev > 0x40)
3785 bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL; 3783 bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL;
3786} 3784}
3787 3785
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index 950334197f40..995c7d0c212a 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -408,7 +408,7 @@ static void b43legacy_phy_setupg(struct b43legacy_wldev *dev)
408 408
409 if (is_bcm_board_vendor(dev) && 409 if (is_bcm_board_vendor(dev) &&
410 (dev->dev->bus->boardinfo.type == 0x0416) && 410 (dev->dev->bus->boardinfo.type == 0x0416) &&
411 (dev->dev->bus->boardinfo.rev == 0x0017)) 411 (dev->dev->bus->sprom.board_rev == 0x0017))
412 return; 412 return;
413 413
414 b43legacy_ilt_write(dev, 0x5001, 0x0002); 414 b43legacy_ilt_write(dev, 0x5001, 0x0002);
@@ -424,7 +424,7 @@ static void b43legacy_phy_setupg(struct b43legacy_wldev *dev)
424 424
425 if (is_bcm_board_vendor(dev) && 425 if (is_bcm_board_vendor(dev) &&
426 (dev->dev->bus->boardinfo.type == 0x0416) && 426 (dev->dev->bus->boardinfo.type == 0x0416) &&
427 (dev->dev->bus->boardinfo.rev == 0x0017)) 427 (dev->dev->bus->sprom.board_rev == 0x0017))
428 return; 428 return;
429 429
430 b43legacy_ilt_write(dev, 0x0401, 0x0002); 430 b43legacy_ilt_write(dev, 0x0401, 0x0002);
diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c
index fcbafcd603cc..896177690394 100644
--- a/drivers/net/wireless/b43legacy/radio.c
+++ b/drivers/net/wireless/b43legacy/radio.c
@@ -1998,7 +1998,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev)
1998 if (phy->type == B43legacy_PHYTYPE_G) { 1998 if (phy->type == B43legacy_PHYTYPE_G) {
1999 if (is_bcm_board_vendor(dev) && 1999 if (is_bcm_board_vendor(dev) &&
2000 dev->dev->bus->boardinfo.type == 0x421 && 2000 dev->dev->bus->boardinfo.type == 0x421 &&
2001 dev->dev->bus->boardinfo.rev >= 30) 2001 dev->dev->bus->sprom.board_rev >= 30)
2002 att = 3; 2002 att = 3;
2003 else if (is_bcm_board_vendor(dev) && 2003 else if (is_bcm_board_vendor(dev) &&
2004 dev->dev->bus->boardinfo.type == 0x416) 2004 dev->dev->bus->boardinfo.type == 0x416)
@@ -2008,7 +2008,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev)
2008 } else { 2008 } else {
2009 if (is_bcm_board_vendor(dev) && 2009 if (is_bcm_board_vendor(dev) &&
2010 dev->dev->bus->boardinfo.type == 0x421 && 2010 dev->dev->bus->boardinfo.type == 0x421 &&
2011 dev->dev->bus->boardinfo.rev >= 30) 2011 dev->dev->bus->sprom.board_rev >= 30)
2012 att = 7; 2012 att = 7;
2013 else 2013 else
2014 att = 6; 2014 att = 6;
@@ -2018,7 +2018,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev)
2018 if (phy->type == B43legacy_PHYTYPE_G) { 2018 if (phy->type == B43legacy_PHYTYPE_G) {
2019 if (is_bcm_board_vendor(dev) && 2019 if (is_bcm_board_vendor(dev) &&
2020 dev->dev->bus->boardinfo.type == 0x421 && 2020 dev->dev->bus->boardinfo.type == 0x421 &&
2021 dev->dev->bus->boardinfo.rev >= 30) 2021 dev->dev->bus->sprom.board_rev >= 30)
2022 att = 3; 2022 att = 3;
2023 else if (is_bcm_board_vendor(dev) && 2023 else if (is_bcm_board_vendor(dev) &&
2024 dev->dev->bus->boardinfo.type == 2024 dev->dev->bus->boardinfo.type ==
@@ -2052,9 +2052,9 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev)
2052 } 2052 }
2053 if (is_bcm_board_vendor(dev) && 2053 if (is_bcm_board_vendor(dev) &&
2054 dev->dev->bus->boardinfo.type == 0x421) { 2054 dev->dev->bus->boardinfo.type == 0x421) {
2055 if (dev->dev->bus->boardinfo.rev < 0x43) 2055 if (dev->dev->bus->sprom.board_rev < 0x43)
2056 att = 2; 2056 att = 2;
2057 else if (dev->dev->bus->boardinfo.rev < 0x51) 2057 else if (dev->dev->bus->sprom.board_rev < 0x51)
2058 att = 3; 2058 att = 3;
2059 } 2059 }
2060 if (att == 0xFFFF) 2060 if (att == 0xFFFF)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 4add7da24681..e2480d196276 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -85,18 +85,15 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
85 sdiodev->irq_wake = true; 85 sdiodev->irq_wake = true;
86 86
87 /* must configure SDIO_CCCR_IENx to enable irq */ 87 /* must configure SDIO_CCCR_IENx to enable irq */
88 data = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_0, 88 data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
89 SDIO_CCCR_IENx, &ret);
90 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; 89 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
91 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_IENx, 90 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
92 data, &ret);
93 91
94 /* redirect, configure ane enable io for interrupt signal */ 92 /* redirect, configure ane enable io for interrupt signal */
95 data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; 93 data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
96 if (sdiodev->irq_flags | IRQF_TRIGGER_HIGH) 94 if (sdiodev->irq_flags | IRQF_TRIGGER_HIGH)
97 data |= SDIO_SEPINT_ACT_HI; 95 data |= SDIO_SEPINT_ACT_HI;
98 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_BRCM_SEPINT, 96 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
99 data, &ret);
100 97
101 return 0; 98 return 0;
102} 99}
@@ -105,9 +102,8 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
105{ 102{
106 brcmf_dbg(TRACE, "Entering\n"); 103 brcmf_dbg(TRACE, "Entering\n");
107 104
108 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_BRCM_SEPINT, 105 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
109 0, NULL); 106 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
110 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_IENx, 0, NULL);
111 107
112 if (sdiodev->irq_wake) { 108 if (sdiodev->irq_wake) {
113 disable_irq_wake(sdiodev->irq); 109 disable_irq_wake(sdiodev->irq);
@@ -158,153 +154,147 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
158} 154}
159#endif /* CONFIG_BRCMFMAC_SDIO_OOB */ 155#endif /* CONFIG_BRCMFMAC_SDIO_OOB */
160 156
161u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
162 int *err)
163{
164 int status;
165 s32 retry = 0;
166 u8 data = 0;
167
168 do {
169 if (retry) /* wait for 1 ms till bus get settled down */
170 udelay(1000);
171 status = brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, fnc_num,
172 addr, (u8 *) &data);
173 } while (status != 0
174 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
175 if (err)
176 *err = status;
177
178 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
179 fnc_num, addr, data);
180
181 return data;
182}
183
184void
185brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
186 u8 data, int *err)
187{
188 int status;
189 s32 retry = 0;
190
191 do {
192 if (retry) /* wait for 1 ms till bus get settled down */
193 udelay(1000);
194 status = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, fnc_num,
195 addr, (u8 *) &data);
196 } while (status != 0
197 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
198 if (err)
199 *err = status;
200
201 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
202 fnc_num, addr, data);
203}
204
205int 157int
206brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) 158brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
207{ 159{
208 int err = 0; 160 int err = 0, i;
209 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, 161 u8 addr[3];
210 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); 162 s32 retry;
211 if (!err) 163
212 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, 164 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
213 SBSDIO_FUNC1_SBADDRMID, 165 addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
214 (address >> 16) & SBSDIO_SBADDRMID_MASK, 166 addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
215 &err); 167
216 if (!err) 168 for (i = 0; i < 3; i++) {
217 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, 169 retry = 0;
218 SBSDIO_FUNC1_SBADDRHIGH, 170 do {
219 (address >> 24) & SBSDIO_SBADDRHIGH_MASK, 171 if (retry)
220 &err); 172 usleep_range(1000, 2000);
173 err = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE,
174 SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW + i,
175 &addr[i]);
176 } while (err != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
177
178 if (err) {
179 brcmf_dbg(ERROR, "failed at addr:0x%0x\n",
180 SBSDIO_FUNC1_SBADDRLOW + i);
181 break;
182 }
183 }
221 184
222 return err; 185 return err;
223} 186}
224 187
225u32 brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size) 188static int
189brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
190 void *data, bool write)
226{ 191{
227 int status; 192 u8 func_num, reg_size;
228 u32 word = 0; 193 u32 bar;
229 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; 194 s32 retry = 0;
230 195 int ret;
231 brcmf_dbg(INFO, "fun = 1, addr = 0x%x\n", addr);
232
233 if (bar0 != sdiodev->sbwad) {
234 if (brcmf_sdcard_set_sbaddr_window(sdiodev, bar0))
235 return 0xFFFFFFFF;
236 196
237 sdiodev->sbwad = bar0; 197 /*
198 * figure out how to read the register based on address range
199 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
200 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
201 * The rest: function 1 silicon backplane core registers
202 */
203 if ((addr & ~REG_F0_REG_MASK) == 0) {
204 func_num = SDIO_FUNC_0;
205 reg_size = 1;
206 } else if ((addr & ~REG_F1_MISC_MASK) == 0) {
207 func_num = SDIO_FUNC_1;
208 reg_size = 1;
209 } else {
210 func_num = SDIO_FUNC_1;
211 reg_size = 4;
212
213 /* Set the window for SB core register */
214 bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
215 if (bar != sdiodev->sbwad) {
216 ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar);
217 if (ret != 0) {
218 memset(data, 0xFF, reg_size);
219 return ret;
220 }
221 sdiodev->sbwad = bar;
222 }
223 addr &= SBSDIO_SB_OFT_ADDR_MASK;
224 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
238 } 225 }
239 226
240 addr &= SBSDIO_SB_OFT_ADDR_MASK; 227 do {
241 if (size == 4) 228 if (!write)
242 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; 229 memset(data, 0, reg_size);
230 if (retry) /* wait for 1 ms till bus get settled down */
231 usleep_range(1000, 2000);
232 if (reg_size == 1)
233 ret = brcmf_sdioh_request_byte(sdiodev, write,
234 func_num, addr, data);
235 else
236 ret = brcmf_sdioh_request_word(sdiodev, write,
237 func_num, addr, data, 4);
238 } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
243 239
244 status = brcmf_sdioh_request_word(sdiodev, SDIOH_READ, SDIO_FUNC_1, 240 if (ret != 0)
245 addr, &word, size); 241 brcmf_dbg(ERROR, "failed with %d\n", ret);
246 242
247 sdiodev->regfail = (status != 0); 243 return ret;
244}
248 245
249 brcmf_dbg(INFO, "u32data = 0x%x\n", word); 246u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
247{
248 u8 data;
249 int retval;
250 250
251 /* if ok, return appropriately masked word */ 251 brcmf_dbg(INFO, "addr:0x%08x\n", addr);
252 if (status == 0) { 252 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
253 switch (size) { 253 brcmf_dbg(INFO, "data:0x%02x\n", data);
254 case sizeof(u8):
255 return word & 0xff;
256 case sizeof(u16):
257 return word & 0xffff;
258 case sizeof(u32):
259 return word;
260 default:
261 sdiodev->regfail = true;
262 254
263 } 255 if (ret)
264 } 256 *ret = retval;
265 257
266 /* otherwise, bad sdio access or invalid size */ 258 return data;
267 brcmf_dbg(ERROR, "error reading addr 0x%04x size %d\n", addr, size);
268 return 0xFFFFFFFF;
269} 259}
270 260
271u32 brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size, 261u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
272 u32 data)
273{ 262{
274 int status; 263 u32 data;
275 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; 264 int retval;
276 int err = 0;
277 265
278 brcmf_dbg(INFO, "fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", 266 brcmf_dbg(INFO, "addr:0x%08x\n", addr);
279 addr, size * 8, data); 267 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
268 brcmf_dbg(INFO, "data:0x%08x\n", data);
280 269
281 if (bar0 != sdiodev->sbwad) { 270 if (ret)
282 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); 271 *ret = retval;
283 if (err)
284 return err;
285 272
286 sdiodev->sbwad = bar0; 273 return data;
287 } 274}
288 275
289 addr &= SBSDIO_SB_OFT_ADDR_MASK; 276void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
290 if (size == 4) 277 u8 data, int *ret)
291 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; 278{
292 status = 279 int retval;
293 brcmf_sdioh_request_word(sdiodev, SDIOH_WRITE, SDIO_FUNC_1,
294 addr, &data, size);
295 sdiodev->regfail = (status != 0);
296 280
297 if (status == 0) 281 brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data);
298 return 0; 282 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
299 283
300 brcmf_dbg(ERROR, "error writing 0x%08x to addr 0x%04x size %d\n", 284 if (ret)
301 data, addr, size); 285 *ret = retval;
302 return 0xFFFFFFFF;
303} 286}
304 287
305bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev) 288void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
289 u32 data, int *ret)
306{ 290{
307 return sdiodev->regfail; 291 int retval;
292
293 brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data);
294 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
295
296 if (ret)
297 *ret = retval;
308} 298}
309 299
310static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn, 300static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index dd07d33a927c..82f51dbd0d66 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -346,43 +346,17 @@ int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
346 return status; 346 return status;
347} 347}
348 348
349/* Read client card reg */
350static int
351brcmf_sdioh_card_regread(struct brcmf_sdio_dev *sdiodev, int func, u32 regaddr,
352 int regsize, u32 *data)
353{
354
355 if ((func == 0) || (regsize == 1)) {
356 u8 temp = 0;
357
358 brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, func, regaddr,
359 &temp);
360 *data = temp;
361 *data &= 0xff;
362 brcmf_dbg(DATA, "byte read data=0x%02x\n", *data);
363 } else {
364 brcmf_sdioh_request_word(sdiodev, SDIOH_READ, func, regaddr,
365 data, regsize);
366 if (regsize == 2)
367 *data &= 0xffff;
368
369 brcmf_dbg(DATA, "word read data=0x%08x\n", *data);
370 }
371
372 return SUCCESS;
373}
374
375static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr) 349static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
376{ 350{
377 /* read 24 bits and return valid 17 bit addr */ 351 /* read 24 bits and return valid 17 bit addr */
378 int i; 352 int i, ret;
379 u32 scratch, regdata; 353 u32 scratch, regdata;
380 __le32 scratch_le; 354 __le32 scratch_le;
381 u8 *ptr = (u8 *)&scratch_le; 355 u8 *ptr = (u8 *)&scratch_le;
382 356
383 for (i = 0; i < 3; i++) { 357 for (i = 0; i < 3; i++) {
384 if ((brcmf_sdioh_card_regread(sdiodev, 0, regaddr, 1, 358 regdata = brcmf_sdio_regrl(sdiodev, regaddr, &ret);
385 &regdata)) != SUCCESS) 359 if (ret != 0)
386 brcmf_dbg(ERROR, "Can't read!\n"); 360 brcmf_dbg(ERROR, "Can't read!\n");
387 361
388 *ptr++ = (u8) regdata; 362 *ptr++ = (u8) regdata;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 149ee67beb2e..1dbf2be478c8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -629,43 +629,29 @@ static bool data_ok(struct brcmf_sdio *bus)
629 * Reads a register in the SDIO hardware block. This block occupies a series of 629 * Reads a register in the SDIO hardware block. This block occupies a series of
630 * adresses on the 32 bit backplane bus. 630 * adresses on the 32 bit backplane bus.
631 */ 631 */
632static void 632static int
633r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) 633r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
634{ 634{
635 u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); 635 u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
636 *retryvar = 0; 636 int ret;
637 do { 637
638 *regvar = brcmf_sdcard_reg_read(bus->sdiodev, 638 *regvar = brcmf_sdio_regrl(bus->sdiodev,
639 bus->ci->c_inf[idx].base + reg_offset, 639 bus->ci->c_inf[idx].base + offset, &ret);
640 sizeof(u32)); 640
641 } while (brcmf_sdcard_regfail(bus->sdiodev) && 641 return ret;
642 (++(*retryvar) <= retry_limit));
643 if (*retryvar) {
644 bus->regfails += (*retryvar-1);
645 if (*retryvar > retry_limit) {
646 brcmf_dbg(ERROR, "FAILED READ %Xh\n", reg_offset);
647 *regvar = 0;
648 }
649 }
650} 642}
651 643
652static void 644static int
653w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset, u32 *retryvar) 645w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
654{ 646{
655 u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); 647 u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
656 *retryvar = 0; 648 int ret;
657 do { 649
658 brcmf_sdcard_reg_write(bus->sdiodev, 650 brcmf_sdio_regwl(bus->sdiodev,
659 bus->ci->c_inf[idx].base + reg_offset, 651 bus->ci->c_inf[idx].base + reg_offset,
660 sizeof(u32), regval); 652 regval, &ret);
661 } while (brcmf_sdcard_regfail(bus->sdiodev) && 653
662 (++(*retryvar) <= retry_limit)); 654 return ret;
663 if (*retryvar) {
664 bus->regfails += (*retryvar-1);
665 if (*retryvar > retry_limit)
666 brcmf_dbg(ERROR, "FAILED REGISTER WRITE %Xh\n",
667 reg_offset);
668 }
669} 655}
670 656
671#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) 657#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND)
@@ -697,16 +683,16 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
697 clkreq = 683 clkreq =
698 bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; 684 bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
699 685
700 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 686 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
701 SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); 687 clkreq, &err);
702 if (err) { 688 if (err) {
703 brcmf_dbg(ERROR, "HT Avail request error: %d\n", err); 689 brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
704 return -EBADE; 690 return -EBADE;
705 } 691 }
706 692
707 /* Check current status */ 693 /* Check current status */
708 clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, 694 clkctl = brcmf_sdio_regrb(bus->sdiodev,
709 SBSDIO_FUNC1_CHIPCLKCSR, &err); 695 SBSDIO_FUNC1_CHIPCLKCSR, &err);
710 if (err) { 696 if (err) {
711 brcmf_dbg(ERROR, "HT Avail read error: %d\n", err); 697 brcmf_dbg(ERROR, "HT Avail read error: %d\n", err);
712 return -EBADE; 698 return -EBADE;
@@ -715,9 +701,8 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
715 /* Go to pending and await interrupt if appropriate */ 701 /* Go to pending and await interrupt if appropriate */
716 if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { 702 if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
717 /* Allow only clock-available interrupt */ 703 /* Allow only clock-available interrupt */
718 devctl = brcmf_sdcard_cfg_read(bus->sdiodev, 704 devctl = brcmf_sdio_regrb(bus->sdiodev,
719 SDIO_FUNC_1, 705 SBSDIO_DEVICE_CTL, &err);
720 SBSDIO_DEVICE_CTL, &err);
721 if (err) { 706 if (err) {
722 brcmf_dbg(ERROR, "Devctl error setting CA: %d\n", 707 brcmf_dbg(ERROR, "Devctl error setting CA: %d\n",
723 err); 708 err);
@@ -725,30 +710,28 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
725 } 710 }
726 711
727 devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; 712 devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
728 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 713 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
729 SBSDIO_DEVICE_CTL, devctl, &err); 714 devctl, &err);
730 brcmf_dbg(INFO, "CLKCTL: set PENDING\n"); 715 brcmf_dbg(INFO, "CLKCTL: set PENDING\n");
731 bus->clkstate = CLK_PENDING; 716 bus->clkstate = CLK_PENDING;
732 717
733 return 0; 718 return 0;
734 } else if (bus->clkstate == CLK_PENDING) { 719 } else if (bus->clkstate == CLK_PENDING) {
735 /* Cancel CA-only interrupt filter */ 720 /* Cancel CA-only interrupt filter */
736 devctl = 721 devctl = brcmf_sdio_regrb(bus->sdiodev,
737 brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
738 SBSDIO_DEVICE_CTL, &err); 722 SBSDIO_DEVICE_CTL, &err);
739 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; 723 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
740 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 724 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
741 SBSDIO_DEVICE_CTL, devctl, &err); 725 devctl, &err);
742 } 726 }
743 727
744 /* Otherwise, wait here (polling) for HT Avail */ 728 /* Otherwise, wait here (polling) for HT Avail */
745 timeout = jiffies + 729 timeout = jiffies +
746 msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000); 730 msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000);
747 while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { 731 while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
748 clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, 732 clkctl = brcmf_sdio_regrb(bus->sdiodev,
749 SDIO_FUNC_1, 733 SBSDIO_FUNC1_CHIPCLKCSR,
750 SBSDIO_FUNC1_CHIPCLKCSR, 734 &err);
751 &err);
752 if (time_after(jiffies, timeout)) 735 if (time_after(jiffies, timeout))
753 break; 736 break;
754 else 737 else
@@ -781,17 +764,16 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
781 764
782 if (bus->clkstate == CLK_PENDING) { 765 if (bus->clkstate == CLK_PENDING) {
783 /* Cancel CA-only interrupt filter */ 766 /* Cancel CA-only interrupt filter */
784 devctl = brcmf_sdcard_cfg_read(bus->sdiodev, 767 devctl = brcmf_sdio_regrb(bus->sdiodev,
785 SDIO_FUNC_1, 768 SBSDIO_DEVICE_CTL, &err);
786 SBSDIO_DEVICE_CTL, &err);
787 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; 769 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
788 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 770 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
789 SBSDIO_DEVICE_CTL, devctl, &err); 771 devctl, &err);
790 } 772 }
791 773
792 bus->clkstate = CLK_SDONLY; 774 bus->clkstate = CLK_SDONLY;
793 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 775 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
794 SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); 776 clkreq, &err);
795 brcmf_dbg(INFO, "CLKCTL: turned OFF\n"); 777 brcmf_dbg(INFO, "CLKCTL: turned OFF\n");
796 if (err) { 778 if (err) {
797 brcmf_dbg(ERROR, "Failed access turning clock off: %d\n", 779 brcmf_dbg(ERROR, "Failed access turning clock off: %d\n",
@@ -874,7 +856,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
874 856
875static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep) 857static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep)
876{ 858{
877 uint retries = 0; 859 int ret;
878 860
879 brcmf_dbg(INFO, "request %s (currently %s)\n", 861 brcmf_dbg(INFO, "request %s (currently %s)\n",
880 sleep ? "SLEEP" : "WAKE", 862 sleep ? "SLEEP" : "WAKE",
@@ -894,22 +876,20 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep)
894 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 876 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
895 877
896 /* Tell device to start using OOB wakeup */ 878 /* Tell device to start using OOB wakeup */
897 w_sdreg32(bus, SMB_USE_OOB, 879 ret = w_sdreg32(bus, SMB_USE_OOB,
898 offsetof(struct sdpcmd_regs, tosbmailbox), &retries); 880 offsetof(struct sdpcmd_regs, tosbmailbox));
899 if (retries > retry_limit) 881 if (ret != 0)
900 brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"); 882 brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n");
901 883
902 /* Turn off our contribution to the HT clock request */ 884 /* Turn off our contribution to the HT clock request */
903 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); 885 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
904 886
905 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 887 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
906 SBSDIO_FUNC1_CHIPCLKCSR, 888 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
907 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
908 889
909 /* Isolate the bus */ 890 /* Isolate the bus */
910 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 891 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
911 SBSDIO_DEVICE_CTL, 892 SBSDIO_DEVCTL_PADS_ISO, NULL);
912 SBSDIO_DEVCTL_PADS_ISO, NULL);
913 893
914 /* Change state */ 894 /* Change state */
915 bus->sleeping = true; 895 bus->sleeping = true;
@@ -917,21 +897,20 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep)
917 } else { 897 } else {
918 /* Waking up: bus power up is ok, set local state */ 898 /* Waking up: bus power up is ok, set local state */
919 899
920 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 900 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
921 SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); 901 0, NULL);
922 902
923 /* Make sure the controller has the bus up */ 903 /* Make sure the controller has the bus up */
924 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 904 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
925 905
926 /* Send misc interrupt to indicate OOB not needed */ 906 /* Send misc interrupt to indicate OOB not needed */
927 w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, tosbmailboxdata), 907 ret = w_sdreg32(bus, 0,
928 &retries); 908 offsetof(struct sdpcmd_regs, tosbmailboxdata));
929 if (retries <= retry_limit) 909 if (ret == 0)
930 w_sdreg32(bus, SMB_DEV_INT, 910 ret = w_sdreg32(bus, SMB_DEV_INT,
931 offsetof(struct sdpcmd_regs, tosbmailbox), 911 offsetof(struct sdpcmd_regs, tosbmailbox));
932 &retries); 912
933 913 if (ret != 0)
934 if (retries > retry_limit)
935 brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n"); 914 brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n");
936 915
937 /* Make sure we have SD bus access */ 916 /* Make sure we have SD bus access */
@@ -955,17 +934,17 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
955 u32 intstatus = 0; 934 u32 intstatus = 0;
956 u32 hmb_data; 935 u32 hmb_data;
957 u8 fcbits; 936 u8 fcbits;
958 uint retries = 0; 937 int ret;
959 938
960 brcmf_dbg(TRACE, "Enter\n"); 939 brcmf_dbg(TRACE, "Enter\n");
961 940
962 /* Read mailbox data and ack that we did so */ 941 /* Read mailbox data and ack that we did so */
963 r_sdreg32(bus, &hmb_data, 942 ret = r_sdreg32(bus, &hmb_data,
964 offsetof(struct sdpcmd_regs, tohostmailboxdata), &retries); 943 offsetof(struct sdpcmd_regs, tohostmailboxdata));
965 944
966 if (retries <= retry_limit) 945 if (ret == 0)
967 w_sdreg32(bus, SMB_INT_ACK, 946 w_sdreg32(bus, SMB_INT_ACK,
968 offsetof(struct sdpcmd_regs, tosbmailbox), &retries); 947 offsetof(struct sdpcmd_regs, tosbmailbox));
969 bus->f1regdata += 2; 948 bus->f1regdata += 2;
970 949
971 /* Dongle recomposed rx frames, accept them again */ 950 /* Dongle recomposed rx frames, accept them again */
@@ -1040,17 +1019,16 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1040 if (abort) 1019 if (abort)
1041 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 1020 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
1042 1021
1043 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 1022 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
1044 SBSDIO_FUNC1_FRAMECTRL, 1023 SFC_RF_TERM, &err);
1045 SFC_RF_TERM, &err);
1046 bus->f1regdata++; 1024 bus->f1regdata++;
1047 1025
1048 /* Wait until the packet has been flushed (device/FIFO stable) */ 1026 /* Wait until the packet has been flushed (device/FIFO stable) */
1049 for (lastrbc = retries = 0xffff; retries > 0; retries--) { 1027 for (lastrbc = retries = 0xffff; retries > 0; retries--) {
1050 hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, 1028 hi = brcmf_sdio_regrb(bus->sdiodev,
1051 SBSDIO_FUNC1_RFRAMEBCHI, NULL); 1029 SBSDIO_FUNC1_RFRAMEBCHI, &err);
1052 lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, 1030 lo = brcmf_sdio_regrb(bus->sdiodev,
1053 SBSDIO_FUNC1_RFRAMEBCLO, NULL); 1031 SBSDIO_FUNC1_RFRAMEBCLO, &err);
1054 bus->f1regdata += 2; 1032 bus->f1regdata += 2;
1055 1033
1056 if ((hi == 0) && (lo == 0)) 1034 if ((hi == 0) && (lo == 0))
@@ -1070,11 +1048,11 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1070 1048
1071 if (rtx) { 1049 if (rtx) {
1072 bus->rxrtx++; 1050 bus->rxrtx++;
1073 w_sdreg32(bus, SMB_NAK, 1051 err = w_sdreg32(bus, SMB_NAK,
1074 offsetof(struct sdpcmd_regs, tosbmailbox), &retries); 1052 offsetof(struct sdpcmd_regs, tosbmailbox));
1075 1053
1076 bus->f1regdata++; 1054 bus->f1regdata++;
1077 if (retries <= retry_limit) 1055 if (err == 0)
1078 bus->rxskip = true; 1056 bus->rxskip = true;
1079 } 1057 }
1080 1058
@@ -1082,7 +1060,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1082 bus->nextlen = 0; 1060 bus->nextlen = 0;
1083 1061
1084 /* If we can't reach the device, signal failure */ 1062 /* If we can't reach the device, signal failure */
1085 if (err || brcmf_sdcard_regfail(bus->sdiodev)) 1063 if (err)
1086 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 1064 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
1087} 1065}
1088 1066
@@ -2178,21 +2156,16 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
2178 bus->tx_sderrs++; 2156 bus->tx_sderrs++;
2179 2157
2180 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 2158 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
2181 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 2159 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2182 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, 2160 SFC_WF_TERM, NULL);
2183 NULL);
2184 bus->f1regdata++; 2161 bus->f1regdata++;
2185 2162
2186 for (i = 0; i < 3; i++) { 2163 for (i = 0; i < 3; i++) {
2187 u8 hi, lo; 2164 u8 hi, lo;
2188 hi = brcmf_sdcard_cfg_read(bus->sdiodev, 2165 hi = brcmf_sdio_regrb(bus->sdiodev,
2189 SDIO_FUNC_1, 2166 SBSDIO_FUNC1_WFRAMEBCHI, NULL);
2190 SBSDIO_FUNC1_WFRAMEBCHI, 2167 lo = brcmf_sdio_regrb(bus->sdiodev,
2191 NULL); 2168 SBSDIO_FUNC1_WFRAMEBCLO, NULL);
2192 lo = brcmf_sdcard_cfg_read(bus->sdiodev,
2193 SDIO_FUNC_1,
2194 SBSDIO_FUNC1_WFRAMEBCLO,
2195 NULL);
2196 bus->f1regdata += 2; 2169 bus->f1regdata += 2;
2197 if ((hi == 0) && (lo == 0)) 2170 if ((hi == 0) && (lo == 0))
2198 break; 2171 break;
@@ -2219,7 +2192,6 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2219{ 2192{
2220 struct sk_buff *pkt; 2193 struct sk_buff *pkt;
2221 u32 intstatus = 0; 2194 u32 intstatus = 0;
2222 uint retries = 0;
2223 int ret = 0, prec_out; 2195 int ret = 0, prec_out;
2224 uint cnt = 0; 2196 uint cnt = 0;
2225 uint datalen; 2197 uint datalen;
@@ -2249,11 +2221,11 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2249 /* In poll mode, need to check for other events */ 2221 /* In poll mode, need to check for other events */
2250 if (!bus->intr && cnt) { 2222 if (!bus->intr && cnt) {
2251 /* Check device status, signal pending interrupt */ 2223 /* Check device status, signal pending interrupt */
2252 r_sdreg32(bus, &intstatus, 2224 ret = r_sdreg32(bus, &intstatus,
2253 offsetof(struct sdpcmd_regs, intstatus), 2225 offsetof(struct sdpcmd_regs,
2254 &retries); 2226 intstatus));
2255 bus->f2txdata++; 2227 bus->f2txdata++;
2256 if (brcmf_sdcard_regfail(bus->sdiodev)) 2228 if (ret != 0)
2257 break; 2229 break;
2258 if (intstatus & bus->hostintmask) 2230 if (intstatus & bus->hostintmask)
2259 bus->ipend = true; 2231 bus->ipend = true;
@@ -2275,7 +2247,6 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
2275{ 2247{
2276 u32 local_hostintmask; 2248 u32 local_hostintmask;
2277 u8 saveclk; 2249 u8 saveclk;
2278 uint retries;
2279 int err; 2250 int err;
2280 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 2251 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2281 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 2252 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
@@ -2303,7 +2274,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
2303 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 2274 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
2304 2275
2305 /* Disable and clear interrupts at the chip level also */ 2276 /* Disable and clear interrupts at the chip level also */
2306 w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask), &retries); 2277 w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask));
2307 local_hostintmask = bus->hostintmask; 2278 local_hostintmask = bus->hostintmask;
2308 bus->hostintmask = 0; 2279 bus->hostintmask = 0;
2309 2280
@@ -2311,24 +2282,23 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
2311 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 2282 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2312 2283
2313 /* Force clocks on backplane to be sure F2 interrupt propagates */ 2284 /* Force clocks on backplane to be sure F2 interrupt propagates */
2314 saveclk = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, 2285 saveclk = brcmf_sdio_regrb(bus->sdiodev,
2315 SBSDIO_FUNC1_CHIPCLKCSR, &err); 2286 SBSDIO_FUNC1_CHIPCLKCSR, &err);
2316 if (!err) { 2287 if (!err) {
2317 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 2288 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
2318 SBSDIO_FUNC1_CHIPCLKCSR, 2289 (saveclk | SBSDIO_FORCE_HT), &err);
2319 (saveclk | SBSDIO_FORCE_HT), &err);
2320 } 2290 }
2321 if (err) 2291 if (err)
2322 brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err); 2292 brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
2323 2293
2324 /* Turn off the bus (F2), free any pending packets */ 2294 /* Turn off the bus (F2), free any pending packets */
2325 brcmf_dbg(INTR, "disable SDIO interrupts\n"); 2295 brcmf_dbg(INTR, "disable SDIO interrupts\n");
2326 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, 2296 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1,
2327 SDIO_FUNC_ENABLE_1, NULL); 2297 NULL);
2328 2298
2329 /* Clear any pending interrupts now that F2 is disabled */ 2299 /* Clear any pending interrupts now that F2 is disabled */
2330 w_sdreg32(bus, local_hostintmask, 2300 w_sdreg32(bus, local_hostintmask,
2331 offsetof(struct sdpcmd_regs, intstatus), &retries); 2301 offsetof(struct sdpcmd_regs, intstatus));
2332 2302
2333 /* Turn off the backplane clock (only) */ 2303 /* Turn off the backplane clock (only) */
2334 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); 2304 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
@@ -2373,12 +2343,12 @@ static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
2373static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) 2343static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2374{ 2344{
2375 u32 intstatus, newstatus = 0; 2345 u32 intstatus, newstatus = 0;
2376 uint retries = 0;
2377 uint rxlimit = bus->rxbound; /* Rx frames to read before resched */ 2346 uint rxlimit = bus->rxbound; /* Rx frames to read before resched */
2378 uint txlimit = bus->txbound; /* Tx frames to send before resched */ 2347 uint txlimit = bus->txbound; /* Tx frames to send before resched */
2379 uint framecnt = 0; /* Temporary counter of tx/rx frames */ 2348 uint framecnt = 0; /* Temporary counter of tx/rx frames */
2380 bool rxdone = true; /* Flag for no more read data */ 2349 bool rxdone = true; /* Flag for no more read data */
2381 bool resched = false; /* Flag indicating resched wanted */ 2350 bool resched = false; /* Flag indicating resched wanted */
2351 int err;
2382 2352
2383 brcmf_dbg(TRACE, "Enter\n"); 2353 brcmf_dbg(TRACE, "Enter\n");
2384 2354
@@ -2389,13 +2359,12 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2389 2359
2390 /* If waiting for HTAVAIL, check status */ 2360 /* If waiting for HTAVAIL, check status */
2391 if (bus->clkstate == CLK_PENDING) { 2361 if (bus->clkstate == CLK_PENDING) {
2392 int err;
2393 u8 clkctl, devctl = 0; 2362 u8 clkctl, devctl = 0;
2394 2363
2395#ifdef DEBUG 2364#ifdef DEBUG
2396 /* Check for inconsistent device control */ 2365 /* Check for inconsistent device control */
2397 devctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, 2366 devctl = brcmf_sdio_regrb(bus->sdiodev,
2398 SBSDIO_DEVICE_CTL, &err); 2367 SBSDIO_DEVICE_CTL, &err);
2399 if (err) { 2368 if (err) {
2400 brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err); 2369 brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err);
2401 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 2370 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
@@ -2403,8 +2372,8 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2403#endif /* DEBUG */ 2372#endif /* DEBUG */
2404 2373
2405 /* Read CSR, if clock on switch to AVAIL, else ignore */ 2374 /* Read CSR, if clock on switch to AVAIL, else ignore */
2406 clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, 2375 clkctl = brcmf_sdio_regrb(bus->sdiodev,
2407 SBSDIO_FUNC1_CHIPCLKCSR, &err); 2376 SBSDIO_FUNC1_CHIPCLKCSR, &err);
2408 if (err) { 2377 if (err) {
2409 brcmf_dbg(ERROR, "error reading CSR: %d\n", 2378 brcmf_dbg(ERROR, "error reading CSR: %d\n",
2410 err); 2379 err);
@@ -2415,17 +2384,16 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2415 devctl, clkctl); 2384 devctl, clkctl);
2416 2385
2417 if (SBSDIO_HTAV(clkctl)) { 2386 if (SBSDIO_HTAV(clkctl)) {
2418 devctl = brcmf_sdcard_cfg_read(bus->sdiodev, 2387 devctl = brcmf_sdio_regrb(bus->sdiodev,
2419 SDIO_FUNC_1, 2388 SBSDIO_DEVICE_CTL, &err);
2420 SBSDIO_DEVICE_CTL, &err);
2421 if (err) { 2389 if (err) {
2422 brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", 2390 brcmf_dbg(ERROR, "error reading DEVCTL: %d\n",
2423 err); 2391 err);
2424 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 2392 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2425 } 2393 }
2426 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; 2394 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
2427 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 2395 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
2428 SBSDIO_DEVICE_CTL, devctl, &err); 2396 devctl, &err);
2429 if (err) { 2397 if (err) {
2430 brcmf_dbg(ERROR, "error writing DEVCTL: %d\n", 2398 brcmf_dbg(ERROR, "error writing DEVCTL: %d\n",
2431 err); 2399 err);
@@ -2447,17 +2415,17 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2447 /* Pending interrupt indicates new device status */ 2415 /* Pending interrupt indicates new device status */
2448 if (bus->ipend) { 2416 if (bus->ipend) {
2449 bus->ipend = false; 2417 bus->ipend = false;
2450 r_sdreg32(bus, &newstatus, 2418 err = r_sdreg32(bus, &newstatus,
2451 offsetof(struct sdpcmd_regs, intstatus), &retries); 2419 offsetof(struct sdpcmd_regs, intstatus));
2452 bus->f1regdata++; 2420 bus->f1regdata++;
2453 if (brcmf_sdcard_regfail(bus->sdiodev)) 2421 if (err != 0)
2454 newstatus = 0; 2422 newstatus = 0;
2455 newstatus &= bus->hostintmask; 2423 newstatus &= bus->hostintmask;
2456 bus->fcstate = !!(newstatus & I_HMB_FC_STATE); 2424 bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
2457 if (newstatus) { 2425 if (newstatus) {
2458 w_sdreg32(bus, newstatus, 2426 err = w_sdreg32(bus, newstatus,
2459 offsetof(struct sdpcmd_regs, intstatus), 2427 offsetof(struct sdpcmd_regs,
2460 &retries); 2428 intstatus));
2461 bus->f1regdata++; 2429 bus->f1regdata++;
2462 } 2430 }
2463 } 2431 }
@@ -2472,11 +2440,11 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2472 */ 2440 */
2473 if (intstatus & I_HMB_FC_CHANGE) { 2441 if (intstatus & I_HMB_FC_CHANGE) {
2474 intstatus &= ~I_HMB_FC_CHANGE; 2442 intstatus &= ~I_HMB_FC_CHANGE;
2475 w_sdreg32(bus, I_HMB_FC_CHANGE, 2443 err = w_sdreg32(bus, I_HMB_FC_CHANGE,
2476 offsetof(struct sdpcmd_regs, intstatus), &retries); 2444 offsetof(struct sdpcmd_regs, intstatus));
2477 2445
2478 r_sdreg32(bus, &newstatus, 2446 err = r_sdreg32(bus, &newstatus,
2479 offsetof(struct sdpcmd_regs, intstatus), &retries); 2447 offsetof(struct sdpcmd_regs, intstatus));
2480 bus->f1regdata += 2; 2448 bus->f1regdata += 2;
2481 bus->fcstate = 2449 bus->fcstate =
2482 !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); 2450 !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
@@ -2546,21 +2514,18 @@ clkwait:
2546 2514
2547 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 2515 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
2548 2516
2549 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 2517 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2550 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, 2518 SFC_WF_TERM, &err);
2551 NULL);
2552 bus->f1regdata++; 2519 bus->f1regdata++;
2553 2520
2554 for (i = 0; i < 3; i++) { 2521 for (i = 0; i < 3; i++) {
2555 u8 hi, lo; 2522 u8 hi, lo;
2556 hi = brcmf_sdcard_cfg_read(bus->sdiodev, 2523 hi = brcmf_sdio_regrb(bus->sdiodev,
2557 SDIO_FUNC_1, 2524 SBSDIO_FUNC1_WFRAMEBCHI,
2558 SBSDIO_FUNC1_WFRAMEBCHI, 2525 &err);
2559 NULL); 2526 lo = brcmf_sdio_regrb(bus->sdiodev,
2560 lo = brcmf_sdcard_cfg_read(bus->sdiodev, 2527 SBSDIO_FUNC1_WFRAMEBCLO,
2561 SDIO_FUNC_1, 2528 &err);
2562 SBSDIO_FUNC1_WFRAMEBCLO,
2563 NULL);
2564 bus->f1regdata += 2; 2529 bus->f1regdata += 2;
2565 if ((hi == 0) && (lo == 0)) 2530 if ((hi == 0) && (lo == 0))
2566 break; 2531 break;
@@ -2587,10 +2552,8 @@ clkwait:
2587 else await next interrupt */ 2552 else await next interrupt */
2588 /* On failed register access, all bets are off: 2553 /* On failed register access, all bets are off:
2589 no resched or interrupts */ 2554 no resched or interrupts */
2590 if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || 2555 if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) {
2591 brcmf_sdcard_regfail(bus->sdiodev)) { 2556 brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation\n");
2592 brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation %d\n",
2593 brcmf_sdcard_regfail(bus->sdiodev));
2594 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 2557 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2595 bus->intstatus = 0; 2558 bus->intstatus = 0;
2596 } else if (bus->clkstate == CLK_PENDING) { 2559 } else if (bus->clkstate == CLK_PENDING) {
@@ -2886,19 +2849,16 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
2886 2849
2887 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 2850 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
2888 2851
2889 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 2852 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2890 SBSDIO_FUNC1_FRAMECTRL, 2853 SFC_WF_TERM, NULL);
2891 SFC_WF_TERM, NULL);
2892 bus->f1regdata++; 2854 bus->f1regdata++;
2893 2855
2894 for (i = 0; i < 3; i++) { 2856 for (i = 0; i < 3; i++) {
2895 u8 hi, lo; 2857 u8 hi, lo;
2896 hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, 2858 hi = brcmf_sdio_regrb(bus->sdiodev,
2897 SBSDIO_FUNC1_WFRAMEBCHI, 2859 SBSDIO_FUNC1_WFRAMEBCHI, NULL);
2898 NULL); 2860 lo = brcmf_sdio_regrb(bus->sdiodev,
2899 lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, 2861 SBSDIO_FUNC1_WFRAMEBCLO, NULL);
2900 SBSDIO_FUNC1_WFRAMEBCLO,
2901 NULL);
2902 bus->f1regdata += 2; 2862 bus->f1regdata += 2;
2903 if (hi == 0 && lo == 0) 2863 if (hi == 0 && lo == 0)
2904 break; 2864 break;
@@ -3188,7 +3148,6 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
3188 3148
3189static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) 3149static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
3190{ 3150{
3191 uint retries;
3192 int bcmerror = 0; 3151 int bcmerror = 0;
3193 struct chip_info *ci = bus->ci; 3152 struct chip_info *ci = bus->ci;
3194 3153
@@ -3222,7 +3181,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
3222 } 3181 }
3223 3182
3224 w_sdreg32(bus, 0xFFFFFFFF, 3183 w_sdreg32(bus, 0xFFFFFFFF,
3225 offsetof(struct sdpcmd_regs, intstatus), &retries); 3184 offsetof(struct sdpcmd_regs, intstatus));
3226 3185
3227 ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); 3186 ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3);
3228 3187
@@ -3444,7 +3403,6 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3444 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 3403 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
3445 struct brcmf_sdio *bus = sdiodev->bus; 3404 struct brcmf_sdio *bus = sdiodev->bus;
3446 unsigned long timeout; 3405 unsigned long timeout;
3447 uint retries = 0;
3448 u8 ready, enable; 3406 u8 ready, enable;
3449 int err, ret = 0; 3407 int err, ret = 0;
3450 u8 saveclk; 3408 u8 saveclk;
@@ -3472,13 +3430,11 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3472 goto exit; 3430 goto exit;
3473 3431
3474 /* Force clocks on backplane to be sure F2 interrupt propagates */ 3432 /* Force clocks on backplane to be sure F2 interrupt propagates */
3475 saveclk = 3433 saveclk = brcmf_sdio_regrb(bus->sdiodev,
3476 brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, 3434 SBSDIO_FUNC1_CHIPCLKCSR, &err);
3477 SBSDIO_FUNC1_CHIPCLKCSR, &err);
3478 if (!err) { 3435 if (!err) {
3479 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 3436 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
3480 SBSDIO_FUNC1_CHIPCLKCSR, 3437 (saveclk | SBSDIO_FORCE_HT), &err);
3481 (saveclk | SBSDIO_FORCE_HT), &err);
3482 } 3438 }
3483 if (err) { 3439 if (err) {
3484 brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err); 3440 brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
@@ -3487,17 +3443,16 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3487 3443
3488 /* Enable function 2 (frame transfers) */ 3444 /* Enable function 2 (frame transfers) */
3489 w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, 3445 w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
3490 offsetof(struct sdpcmd_regs, tosbmailboxdata), &retries); 3446 offsetof(struct sdpcmd_regs, tosbmailboxdata));
3491 enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); 3447 enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
3492 3448
3493 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, 3449 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
3494 enable, NULL);
3495 3450
3496 timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY); 3451 timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY);
3497 ready = 0; 3452 ready = 0;
3498 while (enable != ready) { 3453 while (enable != ready) {
3499 ready = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_0, 3454 ready = brcmf_sdio_regrb(bus->sdiodev,
3500 SDIO_CCCR_IORx, NULL); 3455 SDIO_CCCR_IORx, NULL);
3501 if (time_after(jiffies, timeout)) 3456 if (time_after(jiffies, timeout))
3502 break; 3457 break;
3503 else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50)) 3458 else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50))
@@ -3512,21 +3467,18 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3512 /* Set up the interrupt mask and enable interrupts */ 3467 /* Set up the interrupt mask and enable interrupts */
3513 bus->hostintmask = HOSTINTMASK; 3468 bus->hostintmask = HOSTINTMASK;
3514 w_sdreg32(bus, bus->hostintmask, 3469 w_sdreg32(bus, bus->hostintmask,
3515 offsetof(struct sdpcmd_regs, hostintmask), &retries); 3470 offsetof(struct sdpcmd_regs, hostintmask));
3516 3471
3517 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 3472 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err);
3518 SBSDIO_WATERMARK, 8, &err);
3519 } else { 3473 } else {
3520 /* Disable F2 again */ 3474 /* Disable F2 again */
3521 enable = SDIO_FUNC_ENABLE_1; 3475 enable = SDIO_FUNC_ENABLE_1;
3522 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, 3476 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
3523 SDIO_CCCR_IOEx, enable, NULL);
3524 ret = -ENODEV; 3477 ret = -ENODEV;
3525 } 3478 }
3526 3479
3527 /* Restore previous clock setting */ 3480 /* Restore previous clock setting */
3528 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 3481 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
3529 SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
3530 3482
3531 if (ret == 0) { 3483 if (ret == 0) {
3532 ret = brcmf_sdio_intr_register(bus->sdiodev); 3484 ret = brcmf_sdio_intr_register(bus->sdiodev);
@@ -3606,9 +3558,9 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3606 3558
3607 if (!bus->dpc_sched) { 3559 if (!bus->dpc_sched) {
3608 u8 devpend; 3560 u8 devpend;
3609 devpend = brcmf_sdcard_cfg_read(bus->sdiodev, 3561 devpend = brcmf_sdio_regrb(bus->sdiodev,
3610 SDIO_FUNC_0, SDIO_CCCR_INTx, 3562 SDIO_CCCR_INTx,
3611 NULL); 3563 NULL);
3612 intstatus = 3564 intstatus =
3613 devpend & (INTR_STATUS_FUNC1 | 3565 devpend & (INTR_STATUS_FUNC1 |
3614 INTR_STATUS_FUNC2); 3566 INTR_STATUS_FUNC2);
@@ -3732,24 +3684,18 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3732 3684
3733 bus->alp_only = true; 3685 bus->alp_only = true;
3734 3686
3735 /* Return the window to backplane enumeration space for core access */
3736 if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE))
3737 brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n");
3738
3739 pr_debug("F1 signature read @0x18000000=0x%4x\n", 3687 pr_debug("F1 signature read @0x18000000=0x%4x\n",
3740 brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4)); 3688 brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
3741 3689
3742 /* 3690 /*
3743 * Force PLL off until brcmf_sdio_chip_attach() 3691 * Force PLL off until brcmf_sdio_chip_attach()
3744 * programs PLL control regs 3692 * programs PLL control regs
3745 */ 3693 */
3746 3694
3747 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 3695 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
3748 SBSDIO_FUNC1_CHIPCLKCSR, 3696 BRCMF_INIT_CLKCTL1, &err);
3749 BRCMF_INIT_CLKCTL1, &err);
3750 if (!err) 3697 if (!err)
3751 clkctl = 3698 clkctl = brcmf_sdio_regrb(bus->sdiodev,
3752 brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
3753 SBSDIO_FUNC1_CHIPCLKCSR, &err); 3699 SBSDIO_FUNC1_CHIPCLKCSR, &err);
3754 3700
3755 if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { 3701 if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
@@ -3782,9 +3728,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3782 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); 3728 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
3783 reg_addr = bus->ci->c_inf[idx].base + 3729 reg_addr = bus->ci->c_inf[idx].base +
3784 offsetof(struct sdpcmd_regs, corecontrol); 3730 offsetof(struct sdpcmd_regs, corecontrol);
3785 reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32)); 3731 reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL);
3786 brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32), 3732 brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL);
3787 reg_val | CC_BPRESEN);
3788 3733
3789 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); 3734 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
3790 3735
@@ -3809,16 +3754,15 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
3809 brcmf_dbg(TRACE, "Enter\n"); 3754 brcmf_dbg(TRACE, "Enter\n");
3810 3755
3811 /* Disable F2 to clear any intermediate frame state on the dongle */ 3756 /* Disable F2 to clear any intermediate frame state on the dongle */
3812 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, 3757 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx,
3813 SDIO_FUNC_ENABLE_1, NULL); 3758 SDIO_FUNC_ENABLE_1, NULL);
3814 3759
3815 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 3760 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
3816 bus->sleeping = false; 3761 bus->sleeping = false;
3817 bus->rxflow = false; 3762 bus->rxflow = false;
3818 3763
3819 /* Done with backplane-dependent accesses, can drop clock... */ 3764 /* Done with backplane-dependent accesses, can drop clock... */
3820 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 3765 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
3821 SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
3822 3766
3823 /* ...and initialize clock/power states */ 3767 /* ...and initialize clock/power states */
3824 bus->clkstate = CLK_SDONLY; 3768 bus->clkstate = CLK_SDONLY;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
index 1534efc21631..f8e1f1c84d08 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
@@ -93,8 +93,9 @@ brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
93 93
94 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 94 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
95 95
96 regdata = brcmf_sdcard_reg_read(sdiodev, 96 regdata = brcmf_sdio_regrl(sdiodev,
97 CORE_SB(ci->c_inf[idx].base, sbidhigh), 4); 97 CORE_SB(ci->c_inf[idx].base, sbidhigh),
98 NULL);
98 return SBCOREREV(regdata); 99 return SBCOREREV(regdata);
99} 100}
100 101
@@ -118,8 +119,9 @@ brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
118 119
119 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 120 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
120 121
121 regdata = brcmf_sdcard_reg_read(sdiodev, 122 regdata = brcmf_sdio_regrl(sdiodev,
122 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); 123 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
124 NULL);
123 regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT | 125 regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
124 SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK); 126 SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
125 return (SSB_TMSLOW_CLOCK == regdata); 127 return (SSB_TMSLOW_CLOCK == regdata);
@@ -135,13 +137,13 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
135 137
136 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 138 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
137 139
138 regdata = brcmf_sdcard_reg_read(sdiodev, 140 regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
139 ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); 141 NULL);
140 ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK; 142 ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
141 143
142 regdata = brcmf_sdcard_reg_read(sdiodev, 144 regdata = brcmf_sdio_regrl(sdiodev,
143 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, 145 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
144 4); 146 NULL);
145 ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0); 147 ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
146 148
147 return ret; 149 return ret;
@@ -151,84 +153,85 @@ static void
151brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, 153brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
152 struct chip_info *ci, u16 coreid) 154 struct chip_info *ci, u16 coreid)
153{ 155{
154 u32 regdata; 156 u32 regdata, base;
155 u8 idx; 157 u8 idx;
156 158
157 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 159 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
160 base = ci->c_inf[idx].base;
158 161
159 regdata = brcmf_sdcard_reg_read(sdiodev, 162 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
160 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
161 if (regdata & SSB_TMSLOW_RESET) 163 if (regdata & SSB_TMSLOW_RESET)
162 return; 164 return;
163 165
164 regdata = brcmf_sdcard_reg_read(sdiodev, 166 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
165 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
166 if ((regdata & SSB_TMSLOW_CLOCK) != 0) { 167 if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
167 /* 168 /*
168 * set target reject and spin until busy is clear 169 * set target reject and spin until busy is clear
169 * (preserve core-specific bits) 170 * (preserve core-specific bits)
170 */ 171 */
171 regdata = brcmf_sdcard_reg_read(sdiodev, 172 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
172 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); 173 NULL);
173 brcmf_sdcard_reg_write(sdiodev, 174 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
174 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 175 regdata | SSB_TMSLOW_REJECT, NULL);
175 4, regdata | SSB_TMSLOW_REJECT); 176
176 177 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
177 regdata = brcmf_sdcard_reg_read(sdiodev, 178 NULL);
178 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
179 udelay(1); 179 udelay(1);
180 SPINWAIT((brcmf_sdcard_reg_read(sdiodev, 180 SPINWAIT((brcmf_sdio_regrl(sdiodev,
181 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4) & 181 CORE_SB(base, sbtmstatehigh),
182 NULL) &
182 SSB_TMSHIGH_BUSY), 100000); 183 SSB_TMSHIGH_BUSY), 100000);
183 184
184 regdata = brcmf_sdcard_reg_read(sdiodev, 185 regdata = brcmf_sdio_regrl(sdiodev,
185 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4); 186 CORE_SB(base, sbtmstatehigh),
187 NULL);
186 if (regdata & SSB_TMSHIGH_BUSY) 188 if (regdata & SSB_TMSHIGH_BUSY)
187 brcmf_dbg(ERROR, "core state still busy\n"); 189 brcmf_dbg(ERROR, "core state still busy\n");
188 190
189 regdata = brcmf_sdcard_reg_read(sdiodev, 191 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
190 CORE_SB(ci->c_inf[idx].base, sbidlow), 4); 192 NULL);
191 if (regdata & SSB_IDLOW_INITIATOR) { 193 if (regdata & SSB_IDLOW_INITIATOR) {
192 regdata = brcmf_sdcard_reg_read(sdiodev, 194 regdata = brcmf_sdio_regrl(sdiodev,
193 CORE_SB(ci->c_inf[idx].base, sbimstate), 4) | 195 CORE_SB(base, sbimstate),
194 SSB_IMSTATE_REJECT; 196 NULL);
195 brcmf_sdcard_reg_write(sdiodev, 197 regdata |= SSB_IMSTATE_REJECT;
196 CORE_SB(ci->c_inf[idx].base, sbimstate), 4, 198 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
197 regdata); 199 regdata, NULL);
198 regdata = brcmf_sdcard_reg_read(sdiodev, 200 regdata = brcmf_sdio_regrl(sdiodev,
199 CORE_SB(ci->c_inf[idx].base, sbimstate), 4); 201 CORE_SB(base, sbimstate),
202 NULL);
200 udelay(1); 203 udelay(1);
201 SPINWAIT((brcmf_sdcard_reg_read(sdiodev, 204 SPINWAIT((brcmf_sdio_regrl(sdiodev,
202 CORE_SB(ci->c_inf[idx].base, sbimstate), 4) & 205 CORE_SB(base, sbimstate),
206 NULL) &
203 SSB_IMSTATE_BUSY), 100000); 207 SSB_IMSTATE_BUSY), 100000);
204 } 208 }
205 209
206 /* set reset and reject while enabling the clocks */ 210 /* set reset and reject while enabling the clocks */
207 brcmf_sdcard_reg_write(sdiodev, 211 regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
208 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, 212 SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
209 (SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | 213 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
210 SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET)); 214 regdata, NULL);
211 regdata = brcmf_sdcard_reg_read(sdiodev, 215 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
212 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); 216 NULL);
213 udelay(10); 217 udelay(10);
214 218
215 /* clear the initiator reject bit */ 219 /* clear the initiator reject bit */
216 regdata = brcmf_sdcard_reg_read(sdiodev, 220 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
217 CORE_SB(ci->c_inf[idx].base, sbidlow), 4); 221 NULL);
218 if (regdata & SSB_IDLOW_INITIATOR) { 222 if (regdata & SSB_IDLOW_INITIATOR) {
219 regdata = brcmf_sdcard_reg_read(sdiodev, 223 regdata = brcmf_sdio_regrl(sdiodev,
220 CORE_SB(ci->c_inf[idx].base, sbimstate), 4) & 224 CORE_SB(base, sbimstate),
221 ~SSB_IMSTATE_REJECT; 225 NULL);
222 brcmf_sdcard_reg_write(sdiodev, 226 regdata &= ~SSB_IMSTATE_REJECT;
223 CORE_SB(ci->c_inf[idx].base, sbimstate), 4, 227 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
224 regdata); 228 regdata, NULL);
225 } 229 }
226 } 230 }
227 231
228 /* leave reset and reject asserted */ 232 /* leave reset and reject asserted */
229 brcmf_sdcard_reg_write(sdiodev, 233 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
230 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, 234 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
231 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
232 udelay(1); 235 udelay(1);
233} 236}
234 237
@@ -242,20 +245,19 @@ brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
242 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 245 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
243 246
244 /* if core is already in reset, just return */ 247 /* if core is already in reset, just return */
245 regdata = brcmf_sdcard_reg_read(sdiodev, 248 regdata = brcmf_sdio_regrl(sdiodev,
246 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, 249 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
247 4); 250 NULL);
248 if ((regdata & BCMA_RESET_CTL_RESET) != 0) 251 if ((regdata & BCMA_RESET_CTL_RESET) != 0)
249 return; 252 return;
250 253
251 brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 254 brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 0, NULL);
252 4, 0); 255 regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
253 regdata = brcmf_sdcard_reg_read(sdiodev, 256 NULL);
254 ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4);
255 udelay(10); 257 udelay(10);
256 258
257 brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, 259 brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
258 4, BCMA_RESET_CTL_RESET); 260 BCMA_RESET_CTL_RESET, NULL);
259 udelay(1); 261 udelay(1);
260} 262}
261 263
@@ -279,41 +281,47 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
279 * set reset while enabling the clock and 281 * set reset while enabling the clock and
280 * forcing them on throughout the core 282 * forcing them on throughout the core
281 */ 283 */
282 brcmf_sdcard_reg_write(sdiodev, 284 brcmf_sdio_regwl(sdiodev,
283 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, 285 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
284 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET); 286 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
285 regdata = brcmf_sdcard_reg_read(sdiodev, 287 NULL);
286 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); 288 regdata = brcmf_sdio_regrl(sdiodev,
289 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
290 NULL);
287 udelay(1); 291 udelay(1);
288 292
289 /* clear any serror */ 293 /* clear any serror */
290 regdata = brcmf_sdcard_reg_read(sdiodev, 294 regdata = brcmf_sdio_regrl(sdiodev,
291 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4); 295 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
296 NULL);
292 if (regdata & SSB_TMSHIGH_SERR) 297 if (regdata & SSB_TMSHIGH_SERR)
293 brcmf_sdcard_reg_write(sdiodev, 298 brcmf_sdio_regwl(sdiodev,
294 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4, 0); 299 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
300 0, NULL);
295 301
296 regdata = brcmf_sdcard_reg_read(sdiodev, 302 regdata = brcmf_sdio_regrl(sdiodev,
297 CORE_SB(ci->c_inf[idx].base, sbimstate), 4); 303 CORE_SB(ci->c_inf[idx].base, sbimstate),
304 NULL);
298 if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) 305 if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
299 brcmf_sdcard_reg_write(sdiodev, 306 brcmf_sdio_regwl(sdiodev,
300 CORE_SB(ci->c_inf[idx].base, sbimstate), 4, 307 CORE_SB(ci->c_inf[idx].base, sbimstate),
301 regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO)); 308 regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
309 NULL);
302 310
303 /* clear reset and allow it to propagate throughout the core */ 311 /* clear reset and allow it to propagate throughout the core */
304 brcmf_sdcard_reg_write(sdiodev, 312 brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
305 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, 313 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
306 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK); 314 regdata = brcmf_sdio_regrl(sdiodev,
307 regdata = brcmf_sdcard_reg_read(sdiodev, 315 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
308 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); 316 NULL);
309 udelay(1); 317 udelay(1);
310 318
311 /* leave clock enabled */ 319 /* leave clock enabled */
312 brcmf_sdcard_reg_write(sdiodev, 320 brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
313 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 321 SSB_TMSLOW_CLOCK, NULL);
314 4, SSB_TMSLOW_CLOCK); 322 regdata = brcmf_sdio_regrl(sdiodev,
315 regdata = brcmf_sdcard_reg_read(sdiodev, 323 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
316 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); 324 NULL);
317 udelay(1); 325 udelay(1);
318} 326}
319 327
@@ -330,18 +338,18 @@ brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
330 brcmf_sdio_ai_coredisable(sdiodev, ci, coreid); 338 brcmf_sdio_ai_coredisable(sdiodev, ci, coreid);
331 339
332 /* now do initialization sequence */ 340 /* now do initialization sequence */
333 brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 341 brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
334 4, BCMA_IOCTL_FGC | BCMA_IOCTL_CLK); 342 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
335 regdata = brcmf_sdcard_reg_read(sdiodev, 343 regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
336 ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); 344 NULL);
337 brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, 345 brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
338 4, 0); 346 0, NULL);
339 udelay(1); 347 udelay(1);
340 348
341 brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 349 brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
342 4, BCMA_IOCTL_CLK); 350 BCMA_IOCTL_CLK, NULL);
343 regdata = brcmf_sdcard_reg_read(sdiodev, 351 regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
344 ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); 352 NULL);
345 udelay(1); 353 udelay(1);
346} 354}
347 355
@@ -358,8 +366,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
358 */ 366 */
359 ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON; 367 ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
360 ci->c_inf[0].base = regs; 368 ci->c_inf[0].base = regs;
361 regdata = brcmf_sdcard_reg_read(sdiodev, 369 regdata = brcmf_sdio_regrl(sdiodev,
362 CORE_CC_REG(ci->c_inf[0].base, chipid), 4); 370 CORE_CC_REG(ci->c_inf[0].base, chipid),
371 NULL);
363 ci->chip = regdata & CID_ID_MASK; 372 ci->chip = regdata & CID_ID_MASK;
364 ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; 373 ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
365 ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; 374 ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
@@ -428,8 +437,7 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
428 437
429 /* Try forcing SDIO core to do ALPAvail request only */ 438 /* Try forcing SDIO core to do ALPAvail request only */
430 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; 439 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
431 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, 440 brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
432 SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
433 if (err) { 441 if (err) {
434 brcmf_dbg(ERROR, "error writing for HT off\n"); 442 brcmf_dbg(ERROR, "error writing for HT off\n");
435 return err; 443 return err;
@@ -437,8 +445,8 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
437 445
438 /* If register supported, wait for ALPAvail and then force ALP */ 446 /* If register supported, wait for ALPAvail and then force ALP */
439 /* This may take up to 15 milliseconds */ 447 /* This may take up to 15 milliseconds */
440 clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1, 448 clkval = brcmf_sdio_regrb(sdiodev,
441 SBSDIO_FUNC1_CHIPCLKCSR, NULL); 449 SBSDIO_FUNC1_CHIPCLKCSR, NULL);
442 450
443 if ((clkval & ~SBSDIO_AVBITS) != clkset) { 451 if ((clkval & ~SBSDIO_AVBITS) != clkset) {
444 brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n", 452 brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
@@ -446,8 +454,8 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
446 return -EACCES; 454 return -EACCES;
447 } 455 }
448 456
449 SPINWAIT(((clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1, 457 SPINWAIT(((clkval = brcmf_sdio_regrb(sdiodev,
450 SBSDIO_FUNC1_CHIPCLKCSR, NULL)), 458 SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
451 !SBSDIO_ALPAV(clkval)), 459 !SBSDIO_ALPAV(clkval)),
452 PMU_MAX_TRANSITION_DLY); 460 PMU_MAX_TRANSITION_DLY);
453 if (!SBSDIO_ALPAV(clkval)) { 461 if (!SBSDIO_ALPAV(clkval)) {
@@ -457,13 +465,11 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
457 } 465 }
458 466
459 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; 467 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
460 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, 468 brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
461 SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
462 udelay(65); 469 udelay(65);
463 470
464 /* Also, disable the extra SDIO pull-ups */ 471 /* Also, disable the extra SDIO pull-ups */
465 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, 472 brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
466 SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
467 473
468 return 0; 474 return 0;
469} 475}
@@ -472,18 +478,22 @@ static void
472brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, 478brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
473 struct chip_info *ci) 479 struct chip_info *ci)
474{ 480{
481 u32 base = ci->c_inf[0].base;
482
475 /* get chipcommon rev */ 483 /* get chipcommon rev */
476 ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id); 484 ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
477 485
478 /* get chipcommon capabilites */ 486 /* get chipcommon capabilites */
479 ci->c_inf[0].caps = 487 ci->c_inf[0].caps = brcmf_sdio_regrl(sdiodev,
480 brcmf_sdcard_reg_read(sdiodev, 488 CORE_CC_REG(base, capabilities),
481 CORE_CC_REG(ci->c_inf[0].base, capabilities), 4); 489 NULL);
482 490
483 /* get pmu caps & rev */ 491 /* get pmu caps & rev */
484 if (ci->c_inf[0].caps & CC_CAP_PMU) { 492 if (ci->c_inf[0].caps & CC_CAP_PMU) {
485 ci->pmucaps = brcmf_sdcard_reg_read(sdiodev, 493 ci->pmucaps =
486 CORE_CC_REG(ci->c_inf[0].base, pmucapabilities), 4); 494 brcmf_sdio_regrl(sdiodev,
495 CORE_CC_REG(base, pmucapabilities),
496 NULL);
487 ci->pmurev = ci->pmucaps & PCAP_REV_MASK; 497 ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
488 } 498 }
489 499
@@ -523,10 +533,10 @@ int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
523 533
524 brcmf_sdio_chip_buscoresetup(sdiodev, ci); 534 brcmf_sdio_chip_buscoresetup(sdiodev, ci);
525 535
526 brcmf_sdcard_reg_write(sdiodev, 536 brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
527 CORE_CC_REG(ci->c_inf[0].base, gpiopullup), 4, 0); 537 0, NULL);
528 brcmf_sdcard_reg_write(sdiodev, 538 brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
529 CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), 4, 0); 539 0, NULL);
530 540
531 *ci_ptr = ci; 541 *ci_ptr = ci;
532 return 0; 542 return 0;
@@ -562,6 +572,7 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
562 u32 str_mask = 0; 572 u32 str_mask = 0;
563 u32 str_shift = 0; 573 u32 str_shift = 0;
564 char chn[8]; 574 char chn[8];
575 u32 base = ci->c_inf[0].base;
565 576
566 if (!(ci->c_inf[0].caps & CC_CAP_PMU)) 577 if (!(ci->c_inf[0].caps & CC_CAP_PMU))
567 return; 578 return;
@@ -591,17 +602,17 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
591 } 602 }
592 } 603 }
593 604
594 brcmf_sdcard_reg_write(sdiodev, 605 brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr),
595 CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), 606 1, NULL);
596 4, 1); 607 cc_data_temp =
597 cc_data_temp = brcmf_sdcard_reg_read(sdiodev, 608 brcmf_sdio_regrl(sdiodev,
598 CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), 4); 609 CORE_CC_REG(base, chipcontrol_addr),
610 NULL);
599 cc_data_temp &= ~str_mask; 611 cc_data_temp &= ~str_mask;
600 drivestrength_sel <<= str_shift; 612 drivestrength_sel <<= str_shift;
601 cc_data_temp |= drivestrength_sel; 613 cc_data_temp |= drivestrength_sel;
602 brcmf_sdcard_reg_write(sdiodev, 614 brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr),
603 CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), 615 cc_data_temp, NULL);
604 4, cc_data_temp);
605 616
606 brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n", 617 brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
607 drivestrength, cc_data_temp); 618 drivestrength, cc_data_temp);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 7010eaf71f99..29bf78d264e0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -40,6 +40,10 @@
40/* Maximum number of I/O funcs */ 40/* Maximum number of I/O funcs */
41#define SDIOD_MAX_IOFUNCS 7 41#define SDIOD_MAX_IOFUNCS 7
42 42
43/* mask of register map */
44#define REG_F0_REG_MASK 0x7FF
45#define REG_F1_MISC_MASK 0x1FFFF
46
43/* as of sdiod rev 0, supports 3 functions */ 47/* as of sdiod rev 0, supports 3 functions */
44#define SBSDIO_NUM_FUNCTION 3 48#define SBSDIO_NUM_FUNCTION 3
45 49
@@ -142,7 +146,6 @@ struct brcmf_sdio_dev {
142 u8 num_funcs; /* Supported funcs on client */ 146 u8 num_funcs; /* Supported funcs on client */
143 u32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; 147 u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
144 u32 sbwad; /* Save backplane window address */ 148 u32 sbwad; /* Save backplane window address */
145 bool regfail; /* status of last reg_r/w call */
146 void *bus; 149 void *bus;
147 atomic_t suspend; /* suspend flag */ 150 atomic_t suspend; /* suspend flag */
148 wait_queue_head_t request_byte_wait; 151 wait_queue_head_t request_byte_wait;
@@ -164,31 +167,13 @@ struct brcmf_sdio_dev {
164extern int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev); 167extern int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev);
165extern int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev); 168extern int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev);
166 169
167/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface). 170/* sdio device register access interface */
168 * fn: function number 171extern u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
169 * addr: unmodified SDIO-space address 172extern u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
170 * data: data byte to write 173extern void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
171 * err: pointer to error code (or NULL) 174 u8 data, int *ret);
172 */ 175extern void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
173extern u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint func, 176 u32 data, int *ret);
174 u32 addr, int *err);
175extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint func,
176 u32 addr, u8 data, int *err);
177
178/* Synchronous access to device (client) core registers via CMD53 to F1.
179 * addr: backplane address (i.e. >= regsva from attach)
180 * size: register width in bytes (2 or 4)
181 * data: data for register write
182 */
183extern u32
184brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size);
185
186extern u32
187brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size,
188 u32 data);
189
190/* Indicate if last reg read/write failed */
191extern bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev);
192 177
193/* Buffer transfer to/from device (client) core via cmd53. 178/* Buffer transfer to/from device (client) core via cmd53.
194 * fn: function number 179 * fn: function number
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
index c2eb2d0af386..e227c4c68ef9 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
@@ -39,10 +39,7 @@ BRCMSMAC_OFILES := \
39 phy/phytbl_lcn.o \ 39 phy/phytbl_lcn.o \
40 phy/phytbl_n.o \ 40 phy/phytbl_n.o \
41 phy/phy_qmath.o \ 41 phy/phy_qmath.o \
42 otp.o \
43 srom.o \
44 dma.o \ 42 dma.o \
45 nicpci.o \
46 brcms_trace_events.o 43 brcms_trace_events.o
47 44
48MODULEPFX := brcmsmac 45MODULEPFX := brcmsmac
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
index c93ea35bceec..6d8b7213643a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
@@ -19,7 +19,6 @@
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 20
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/pci.h>
23 22
24#include <defs.h> 23#include <defs.h>
25#include <chipcommon.h> 24#include <chipcommon.h>
@@ -29,8 +28,6 @@
29#include "types.h" 28#include "types.h"
30#include "pub.h" 29#include "pub.h"
31#include "pmu.h" 30#include "pmu.h"
32#include "srom.h"
33#include "nicpci.h"
34#include "aiutils.h" 31#include "aiutils.h"
35 32
36/* slow_clk_ctl */ 33/* slow_clk_ctl */
@@ -321,7 +318,6 @@
321#define IS_SIM(chippkg) \ 318#define IS_SIM(chippkg) \
322 ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) 319 ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
323 320
324#define PCI(sih) (ai_get_buscoretype(sih) == PCI_CORE_ID)
325#define PCIE(sih) (ai_get_buscoretype(sih) == PCIE_CORE_ID) 321#define PCIE(sih) (ai_get_buscoretype(sih) == PCIE_CORE_ID)
326 322
327#define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID)) 323#define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID))
@@ -454,36 +450,9 @@ struct aidmp {
454 u32 componentid3; /* 0xffc */ 450 u32 componentid3; /* 0xffc */
455}; 451};
456 452
457/* return true if PCIE capability exists in the pci config space */
458static bool ai_ispcie(struct si_info *sii)
459{
460 u8 cap_ptr;
461
462 cap_ptr =
463 pcicore_find_pci_capability(sii->pcibus, PCI_CAP_ID_EXP, NULL,
464 NULL);
465 if (!cap_ptr)
466 return false;
467
468 return true;
469}
470
471static bool ai_buscore_prep(struct si_info *sii)
472{
473 /* kludge to enable the clock on the 4306 which lacks a slowclock */
474 if (!ai_ispcie(sii))
475 ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
476 return true;
477}
478
479static bool 453static bool
480ai_buscore_setup(struct si_info *sii, struct bcma_device *cc) 454ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
481{ 455{
482 struct bcma_device *pci = NULL;
483 struct bcma_device *pcie = NULL;
484 struct bcma_device *core;
485
486
487 /* no cores found, bail out */ 456 /* no cores found, bail out */
488 if (cc->bus->nr_cores == 0) 457 if (cc->bus->nr_cores == 0)
489 return false; 458 return false;
@@ -492,8 +461,7 @@ ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
492 sii->pub.ccrev = cc->id.rev; 461 sii->pub.ccrev = cc->id.rev;
493 462
494 /* get chipcommon chipstatus */ 463 /* get chipcommon chipstatus */
495 if (ai_get_ccrev(&sii->pub) >= 11) 464 sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus));
496 sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus));
497 465
498 /* get chipcommon capabilites */ 466 /* get chipcommon capabilites */
499 sii->pub.cccaps = bcma_read32(cc, CHIPCREGOFFS(capabilities)); 467 sii->pub.cccaps = bcma_read32(cc, CHIPCREGOFFS(capabilities));
@@ -506,64 +474,18 @@ ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
506 } 474 }
507 475
508 /* figure out buscore */ 476 /* figure out buscore */
509 list_for_each_entry(core, &cc->bus->cores, list) { 477 sii->buscore = ai_findcore(&sii->pub, PCIE_CORE_ID, 0);
510 uint cid, crev;
511
512 cid = core->id.id;
513 crev = core->id.rev;
514
515 if (cid == PCI_CORE_ID) {
516 pci = core;
517 } else if (cid == PCIE_CORE_ID) {
518 pcie = core;
519 }
520 }
521
522 if (pci && pcie) {
523 if (ai_ispcie(sii))
524 pci = NULL;
525 else
526 pcie = NULL;
527 }
528 if (pci) {
529 sii->buscore = pci;
530 } else if (pcie) {
531 sii->buscore = pcie;
532 }
533
534 /* fixup necessary chip/core configurations */
535 if (!sii->pch) {
536 sii->pch = pcicore_init(&sii->pub, sii->icbus->drv_pci.core);
537 if (sii->pch == NULL)
538 return false;
539 }
540 if (ai_pci_fixcfg(&sii->pub))
541 return false;
542 478
543 return true; 479 return true;
544} 480}
545 481
546/*
547 * get boardtype and boardrev
548 */
549static __used void ai_nvram_process(struct si_info *sii)
550{
551 uint w = 0;
552
553 /* do a pci config read to get subsystem id and subvendor id */
554 pci_read_config_dword(sii->pcibus, PCI_SUBSYSTEM_VENDOR_ID, &w);
555
556 sii->pub.boardvendor = w & 0xffff;
557 sii->pub.boardtype = (w >> 16) & 0xffff;
558}
559
560static struct si_info *ai_doattach(struct si_info *sii, 482static struct si_info *ai_doattach(struct si_info *sii,
561 struct bcma_bus *pbus) 483 struct bcma_bus *pbus)
562{ 484{
563 struct si_pub *sih = &sii->pub; 485 struct si_pub *sih = &sii->pub;
564 u32 w, savewin; 486 u32 w, savewin;
565 struct bcma_device *cc; 487 struct bcma_device *cc;
566 uint socitype; 488 struct ssb_sprom *sprom = &pbus->sprom;
567 489
568 savewin = 0; 490 savewin = 0;
569 491
@@ -573,38 +495,15 @@ static struct si_info *ai_doattach(struct si_info *sii,
573 /* switch to Chipcommon core */ 495 /* switch to Chipcommon core */
574 cc = pbus->drv_cc.core; 496 cc = pbus->drv_cc.core;
575 497
576 /* bus/core/clk setup for register access */ 498 sih->chip = pbus->chipinfo.id;
577 if (!ai_buscore_prep(sii)) 499 sih->chiprev = pbus->chipinfo.rev;
578 return NULL; 500 sih->chippkg = pbus->chipinfo.pkg;
501 sih->boardvendor = pbus->boardinfo.vendor;
502 sih->boardtype = pbus->boardinfo.type;
579 503
580 /*
581 * ChipID recognition.
582 * We assume we can read chipid at offset 0 from the regs arg.
583 * If we add other chiptypes (or if we need to support old sdio
584 * hosts w/o chipcommon), some way of recognizing them needs to
585 * be added here.
586 */
587 w = bcma_read32(cc, CHIPCREGOFFS(chipid));
588 socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
589 /* Might as wll fill in chip id rev & pkg */
590 sih->chip = w & CID_ID_MASK;
591 sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
592 sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
593
594 /* scan for cores */
595 if (socitype != SOCI_AI)
596 return NULL;
597
598 SI_MSG("Found chip type AI (0x%08x)\n", w);
599 if (!ai_buscore_setup(sii, cc)) 504 if (!ai_buscore_setup(sii, cc))
600 goto exit; 505 goto exit;
601 506
602 /* Init nvram from sprom/otp if they exist */
603 if (srom_var_init(&sii->pub))
604 goto exit;
605
606 ai_nvram_process(sii);
607
608 /* === NVRAM, clock is ready === */ 507 /* === NVRAM, clock is ready === */
609 bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0); 508 bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0);
610 bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0); 509 bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0);
@@ -617,15 +516,13 @@ static struct si_info *ai_doattach(struct si_info *sii,
617 } 516 }
618 517
619 /* setup the GPIO based LED powersave register */ 518 /* setup the GPIO based LED powersave register */
620 w = getintvar(sih, BRCMS_SROM_LEDDC); 519 w = (sprom->leddc_on_time << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
520 (sprom->leddc_off_time << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT);
621 if (w == 0) 521 if (w == 0)
622 w = DEFAULT_GPIOTIMERVAL; 522 w = DEFAULT_GPIOTIMERVAL;
623 ai_cc_reg(sih, offsetof(struct chipcregs, gpiotimerval), 523 ai_cc_reg(sih, offsetof(struct chipcregs, gpiotimerval),
624 ~0, w); 524 ~0, w);
625 525
626 if (PCIE(sih))
627 pcicore_attach(sii->pch, SI_DOATTACH);
628
629 if (ai_get_chip_id(sih) == BCM43224_CHIP_ID) { 526 if (ai_get_chip_id(sih) == BCM43224_CHIP_ID) {
630 /* 527 /*
631 * enable 12 mA drive strenth for 43224 and 528 * enable 12 mA drive strenth for 43224 and
@@ -659,9 +556,6 @@ static struct si_info *ai_doattach(struct si_info *sii,
659 return sii; 556 return sii;
660 557
661 exit: 558 exit:
662 if (sii->pch)
663 pcicore_deinit(sii->pch);
664 sii->pch = NULL;
665 559
666 return NULL; 560 return NULL;
667} 561}
@@ -700,11 +594,6 @@ void ai_detach(struct si_pub *sih)
700 if (sii == NULL) 594 if (sii == NULL)
701 return; 595 return;
702 596
703 if (sii->pch)
704 pcicore_deinit(sii->pch);
705 sii->pch = NULL;
706
707 srom_free_vars(sih);
708 kfree(sii); 597 kfree(sii);
709} 598}
710 599
@@ -755,21 +644,7 @@ uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val)
755/* return the slow clock source - LPO, XTAL, or PCI */ 644/* return the slow clock source - LPO, XTAL, or PCI */
756static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc) 645static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc)
757{ 646{
758 struct si_info *sii; 647 return SCC_SS_XTAL;
759 u32 val;
760
761 sii = (struct si_info *)sih;
762 if (ai_get_ccrev(&sii->pub) < 6) {
763 pci_read_config_dword(sii->pcibus, PCI_GPIO_OUT,
764 &val);
765 if (val & PCI_CFG_GPIO_SCS)
766 return SCC_SS_PCI;
767 return SCC_SS_XTAL;
768 } else if (ai_get_ccrev(&sii->pub) < 10) {
769 return bcma_read32(cc, CHIPCREGOFFS(slow_clk_ctl)) &
770 SCC_SS_MASK;
771 } else /* Insta-clock */
772 return SCC_SS_XTAL;
773} 648}
774 649
775/* 650/*
@@ -779,36 +654,12 @@ static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc)
779static uint ai_slowclk_freq(struct si_pub *sih, bool max_freq, 654static uint ai_slowclk_freq(struct si_pub *sih, bool max_freq,
780 struct bcma_device *cc) 655 struct bcma_device *cc)
781{ 656{
782 u32 slowclk;
783 uint div; 657 uint div;
784 658
785 slowclk = ai_slowclk_src(sih, cc); 659 /* Chipc rev 10 is InstaClock */
786 if (ai_get_ccrev(sih) < 6) { 660 div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl));
787 if (slowclk == SCC_SS_PCI) 661 div = 4 * ((div >> SYCC_CD_SHIFT) + 1);
788 return max_freq ? (PCIMAXFREQ / 64) 662 return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
789 : (PCIMINFREQ / 64);
790 else
791 return max_freq ? (XTALMAXFREQ / 32)
792 : (XTALMINFREQ / 32);
793 } else if (ai_get_ccrev(sih) < 10) {
794 div = 4 *
795 (((bcma_read32(cc, CHIPCREGOFFS(slow_clk_ctl)) &
796 SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
797 if (slowclk == SCC_SS_LPO)
798 return max_freq ? LPOMAXFREQ : LPOMINFREQ;
799 else if (slowclk == SCC_SS_XTAL)
800 return max_freq ? (XTALMAXFREQ / div)
801 : (XTALMINFREQ / div);
802 else if (slowclk == SCC_SS_PCI)
803 return max_freq ? (PCIMAXFREQ / div)
804 : (PCIMINFREQ / div);
805 } else {
806 /* Chipc rev 10 is InstaClock */
807 div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl));
808 div = 4 * ((div >> SYCC_CD_SHIFT) + 1);
809 return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
810 }
811 return 0;
812} 663}
813 664
814static void 665static void
@@ -831,8 +682,7 @@ ai_clkctl_setdelay(struct si_pub *sih, struct bcma_device *cc)
831 682
832 /* Starting with 4318 it is ILP that is used for the delays */ 683 /* Starting with 4318 it is ILP that is used for the delays */
833 slowmaxfreq = 684 slowmaxfreq =
834 ai_slowclk_freq(sih, 685 ai_slowclk_freq(sih, false, cc);
835 (ai_get_ccrev(sih) >= 10) ? false : true, cc);
836 686
837 pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; 687 pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
838 fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; 688 fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
@@ -854,9 +704,8 @@ void ai_clkctl_init(struct si_pub *sih)
854 return; 704 return;
855 705
856 /* set all Instaclk chip ILP to 1 MHz */ 706 /* set all Instaclk chip ILP to 1 MHz */
857 if (ai_get_ccrev(sih) >= 10) 707 bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK,
858 bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK, 708 (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
859 (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
860 709
861 ai_clkctl_setdelay(sih, cc); 710 ai_clkctl_setdelay(sih, cc);
862} 711}
@@ -891,140 +740,6 @@ u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih)
891 return fpdelay; 740 return fpdelay;
892} 741}
893 742
894/* turn primary xtal and/or pll off/on */
895int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on)
896{
897 struct si_info *sii;
898 u32 in, out, outen;
899
900 sii = (struct si_info *)sih;
901
902 /* pcie core doesn't have any mapping to control the xtal pu */
903 if (PCIE(sih))
904 return -1;
905
906 pci_read_config_dword(sii->pcibus, PCI_GPIO_IN, &in);
907 pci_read_config_dword(sii->pcibus, PCI_GPIO_OUT, &out);
908 pci_read_config_dword(sii->pcibus, PCI_GPIO_OUTEN, &outen);
909
910 /*
911 * Avoid glitching the clock if GPRS is already using it.
912 * We can't actually read the state of the PLLPD so we infer it
913 * by the value of XTAL_PU which *is* readable via gpioin.
914 */
915 if (on && (in & PCI_CFG_GPIO_XTAL))
916 return 0;
917
918 if (what & XTAL)
919 outen |= PCI_CFG_GPIO_XTAL;
920 if (what & PLL)
921 outen |= PCI_CFG_GPIO_PLL;
922
923 if (on) {
924 /* turn primary xtal on */
925 if (what & XTAL) {
926 out |= PCI_CFG_GPIO_XTAL;
927 if (what & PLL)
928 out |= PCI_CFG_GPIO_PLL;
929 pci_write_config_dword(sii->pcibus,
930 PCI_GPIO_OUT, out);
931 pci_write_config_dword(sii->pcibus,
932 PCI_GPIO_OUTEN, outen);
933 udelay(XTAL_ON_DELAY);
934 }
935
936 /* turn pll on */
937 if (what & PLL) {
938 out &= ~PCI_CFG_GPIO_PLL;
939 pci_write_config_dword(sii->pcibus,
940 PCI_GPIO_OUT, out);
941 mdelay(2);
942 }
943 } else {
944 if (what & XTAL)
945 out &= ~PCI_CFG_GPIO_XTAL;
946 if (what & PLL)
947 out |= PCI_CFG_GPIO_PLL;
948 pci_write_config_dword(sii->pcibus,
949 PCI_GPIO_OUT, out);
950 pci_write_config_dword(sii->pcibus,
951 PCI_GPIO_OUTEN, outen);
952 }
953
954 return 0;
955}
956
957/* clk control mechanism through chipcommon, no policy checking */
958static bool _ai_clkctl_cc(struct si_info *sii, uint mode)
959{
960 struct bcma_device *cc;
961 u32 scc;
962
963 /* chipcommon cores prior to rev6 don't support dynamic clock control */
964 if (ai_get_ccrev(&sii->pub) < 6)
965 return false;
966
967 cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
968
969 if (!(ai_get_cccaps(&sii->pub) & CC_CAP_PWR_CTL) &&
970 (ai_get_ccrev(&sii->pub) < 20))
971 return mode == CLK_FAST;
972
973 switch (mode) {
974 case CLK_FAST: /* FORCEHT, fast (pll) clock */
975 if (ai_get_ccrev(&sii->pub) < 10) {
976 /*
977 * don't forget to force xtal back
978 * on before we clear SCC_DYN_XTAL..
979 */
980 ai_clkctl_xtal(&sii->pub, XTAL, ON);
981 bcma_maskset32(cc, CHIPCREGOFFS(slow_clk_ctl),
982 (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
983 } else if (ai_get_ccrev(&sii->pub) < 20) {
984 bcma_set32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_HR);
985 } else {
986 bcma_set32(cc, CHIPCREGOFFS(clk_ctl_st), CCS_FORCEHT);
987 }
988
989 /* wait for the PLL */
990 if (ai_get_cccaps(&sii->pub) & CC_CAP_PMU) {
991 u32 htavail = CCS_HTAVAIL;
992 SPINWAIT(((bcma_read32(cc, CHIPCREGOFFS(clk_ctl_st)) &
993 htavail) == 0), PMU_MAX_TRANSITION_DLY);
994 } else {
995 udelay(PLL_DELAY);
996 }
997 break;
998
999 case CLK_DYNAMIC: /* enable dynamic clock control */
1000 if (ai_get_ccrev(&sii->pub) < 10) {
1001 scc = bcma_read32(cc, CHIPCREGOFFS(slow_clk_ctl));
1002 scc &= ~(SCC_FS | SCC_IP | SCC_XC);
1003 if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
1004 scc |= SCC_XC;
1005 bcma_write32(cc, CHIPCREGOFFS(slow_clk_ctl), scc);
1006
1007 /*
1008 * for dynamic control, we have to
1009 * release our xtal_pu "force on"
1010 */
1011 if (scc & SCC_XC)
1012 ai_clkctl_xtal(&sii->pub, XTAL, OFF);
1013 } else if (ai_get_ccrev(&sii->pub) < 20) {
1014 /* Instaclock */
1015 bcma_mask32(cc, CHIPCREGOFFS(system_clk_ctl), ~SYCC_HR);
1016 } else {
1017 bcma_mask32(cc, CHIPCREGOFFS(clk_ctl_st), ~CCS_FORCEHT);
1018 }
1019 break;
1020
1021 default:
1022 break;
1023 }
1024
1025 return mode == CLK_FAST;
1026}
1027
1028/* 743/*
1029 * clock control policy function throught chipcommon 744 * clock control policy function throught chipcommon
1030 * 745 *
@@ -1033,133 +748,53 @@ static bool _ai_clkctl_cc(struct si_info *sii, uint mode)
1033 * this is a wrapper over the next internal function 748 * this is a wrapper over the next internal function
1034 * to allow flexible policy settings for outside caller 749 * to allow flexible policy settings for outside caller
1035 */ 750 */
1036bool ai_clkctl_cc(struct si_pub *sih, uint mode) 751bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode)
1037{ 752{
1038 struct si_info *sii; 753 struct si_info *sii;
754 struct bcma_device *cc;
1039 755
1040 sii = (struct si_info *)sih; 756 sii = (struct si_info *)sih;
1041 757
1042 /* chipcommon cores prior to rev6 don't support dynamic clock control */
1043 if (ai_get_ccrev(sih) < 6)
1044 return false;
1045
1046 if (PCI_FORCEHT(sih)) 758 if (PCI_FORCEHT(sih))
1047 return mode == CLK_FAST; 759 return mode == BCMA_CLKMODE_FAST;
1048 760
1049 return _ai_clkctl_cc(sii, mode); 761 cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
762 bcma_core_set_clockmode(cc, mode);
763 return mode == BCMA_CLKMODE_FAST;
1050} 764}
1051 765
1052void ai_pci_up(struct si_pub *sih) 766void ai_pci_up(struct si_pub *sih)
1053{ 767{
1054 struct si_info *sii; 768 struct si_info *sii;
769 struct bcma_device *cc;
1055 770
1056 sii = (struct si_info *)sih; 771 sii = (struct si_info *)sih;
1057 772
1058 if (PCI_FORCEHT(sih)) 773 if (PCI_FORCEHT(sih)) {
1059 _ai_clkctl_cc(sii, CLK_FAST); 774 cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
775 bcma_core_set_clockmode(cc, BCMA_CLKMODE_FAST);
776 }
1060 777
1061 if (PCIE(sih)) 778 if (PCIE(sih))
1062 pcicore_up(sii->pch, SI_PCIUP); 779 bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, true);
1063
1064}
1065
1066/* Unconfigure and/or apply various WARs when system is going to sleep mode */
1067void ai_pci_sleep(struct si_pub *sih)
1068{
1069 struct si_info *sii;
1070
1071 sii = (struct si_info *)sih;
1072
1073 pcicore_sleep(sii->pch);
1074} 780}
1075 781
1076/* Unconfigure and/or apply various WARs when going down */ 782/* Unconfigure and/or apply various WARs when going down */
1077void ai_pci_down(struct si_pub *sih) 783void ai_pci_down(struct si_pub *sih)
1078{ 784{
1079 struct si_info *sii; 785 struct si_info *sii;
786 struct bcma_device *cc;
1080 787
1081 sii = (struct si_info *)sih; 788 sii = (struct si_info *)sih;
1082 789
1083 /* release FORCEHT since chip is going to "down" state */ 790 /* release FORCEHT since chip is going to "down" state */
1084 if (PCI_FORCEHT(sih)) 791 if (PCI_FORCEHT(sih)) {
1085 _ai_clkctl_cc(sii, CLK_DYNAMIC); 792 cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
1086 793 bcma_core_set_clockmode(cc, BCMA_CLKMODE_DYNAMIC);
1087 pcicore_down(sii->pch, SI_PCIDOWN);
1088}
1089
1090/*
1091 * Configure the pci core for pci client (NIC) action
1092 * coremask is the bitvec of cores by index to be enabled.
1093 */
1094void ai_pci_setup(struct si_pub *sih, uint coremask)
1095{
1096 struct si_info *sii;
1097 u32 w;
1098
1099 sii = (struct si_info *)sih;
1100
1101 /*
1102 * Enable sb->pci interrupts. Assume
1103 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
1104 */
1105 if (PCIE(sih) || (PCI(sih) && (ai_get_buscorerev(sih) >= 6))) {
1106 /* pci config write to set this core bit in PCIIntMask */
1107 pci_read_config_dword(sii->pcibus, PCI_INT_MASK, &w);
1108 w |= (coremask << PCI_SBIM_SHIFT);
1109 pci_write_config_dword(sii->pcibus, PCI_INT_MASK, w);
1110 }
1111
1112 if (PCI(sih)) {
1113 pcicore_pci_setup(sii->pch);
1114 } 794 }
1115}
1116 795
1117/* 796 if (PCIE(sih))
1118 * Fixup SROMless PCI device's configuration. 797 bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, false);
1119 * The current core may be changed upon return.
1120 */
1121int ai_pci_fixcfg(struct si_pub *sih)
1122{
1123 struct si_info *sii = (struct si_info *)sih;
1124
1125 /* Fixup PI in SROM shadow area to enable the correct PCI core access */
1126 /* check 'pi' is correct and fix it if not */
1127 pcicore_fixcfg(sii->pch);
1128 pcicore_hwup(sii->pch);
1129 return 0;
1130}
1131
1132/* mask&set gpiocontrol bits */
1133u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val, u8 priority)
1134{
1135 uint regoff;
1136
1137 regoff = offsetof(struct chipcregs, gpiocontrol);
1138 return ai_cc_reg(sih, regoff, mask, val);
1139}
1140
1141void ai_chipcontrl_epa4331(struct si_pub *sih, bool on)
1142{
1143 struct bcma_device *cc;
1144 u32 val;
1145
1146 cc = ai_findcore(sih, CC_CORE_ID, 0);
1147
1148 if (on) {
1149 if (ai_get_chippkg(sih) == 9 || ai_get_chippkg(sih) == 0xb)
1150 /* Ext PA Controls for 4331 12x9 Package */
1151 bcma_set32(cc, CHIPCREGOFFS(chipcontrol),
1152 CCTRL4331_EXTPA_EN |
1153 CCTRL4331_EXTPA_ON_GPIO2_5);
1154 else
1155 /* Ext PA Controls for 4331 12x12 Package */
1156 bcma_set32(cc, CHIPCREGOFFS(chipcontrol),
1157 CCTRL4331_EXTPA_EN);
1158 } else {
1159 val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
1160 bcma_mask32(cc, CHIPCREGOFFS(chipcontrol),
1161 ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5));
1162 }
1163} 798}
1164 799
1165/* Enable BT-COEX & Ex-PA for 4313 */ 800/* Enable BT-COEX & Ex-PA for 4313 */
@@ -1181,6 +816,9 @@ bool ai_deviceremoved(struct si_pub *sih)
1181 816
1182 sii = (struct si_info *)sih; 817 sii = (struct si_info *)sih;
1183 818
819 if (sii->icbus->hosttype != BCMA_HOSTTYPE_PCI)
820 return false;
821
1184 pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w); 822 pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w);
1185 if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM) 823 if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
1186 return true; 824 return true;
@@ -1188,45 +826,6 @@ bool ai_deviceremoved(struct si_pub *sih)
1188 return false; 826 return false;
1189} 827}
1190 828
1191bool ai_is_sprom_available(struct si_pub *sih)
1192{
1193 struct si_info *sii = (struct si_info *)sih;
1194
1195 if (ai_get_ccrev(sih) >= 31) {
1196 struct bcma_device *cc;
1197 u32 sromctrl;
1198
1199 if ((ai_get_cccaps(sih) & CC_CAP_SROM) == 0)
1200 return false;
1201
1202 cc = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
1203 sromctrl = bcma_read32(cc, CHIPCREGOFFS(sromcontrol));
1204 return sromctrl & SRC_PRESENT;
1205 }
1206
1207 switch (ai_get_chip_id(sih)) {
1208 case BCM4313_CHIP_ID:
1209 return (sii->chipst & CST4313_SPROM_PRESENT) != 0;
1210 default:
1211 return true;
1212 }
1213}
1214
1215bool ai_is_otp_disabled(struct si_pub *sih)
1216{
1217 struct si_info *sii = (struct si_info *)sih;
1218
1219 switch (ai_get_chip_id(sih)) {
1220 case BCM4313_CHIP_ID:
1221 return (sii->chipst & CST4313_OTP_PRESENT) == 0;
1222 /* These chips always have their OTP on */
1223 case BCM43224_CHIP_ID:
1224 case BCM43225_CHIP_ID:
1225 default:
1226 return false;
1227 }
1228}
1229
1230uint ai_get_buscoretype(struct si_pub *sih) 829uint ai_get_buscoretype(struct si_pub *sih)
1231{ 830{
1232 struct si_info *sii = (struct si_info *)sih; 831 struct si_info *sii = (struct si_info *)sih;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
index f84c6f781692..d9f04a683bdb 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
@@ -113,10 +113,6 @@
113#define XTAL 0x1 /* primary crystal oscillator (2050) */ 113#define XTAL 0x1 /* primary crystal oscillator (2050) */
114#define PLL 0x2 /* main chip pll */ 114#define PLL 0x2 /* main chip pll */
115 115
116/* clkctl clk mode */
117#define CLK_FAST 0 /* force fast (pll) clock */
118#define CLK_DYNAMIC 2 /* enable dynamic clock control */
119
120/* GPIO usage priorities */ 116/* GPIO usage priorities */
121#define GPIO_DRV_PRIORITY 0 /* Driver */ 117#define GPIO_DRV_PRIORITY 0 /* Driver */
122#define GPIO_APP_PRIORITY 1 /* Application */ 118#define GPIO_APP_PRIORITY 1 /* Application */
@@ -172,9 +168,7 @@ struct si_info {
172 struct si_pub pub; /* back plane public state (must be first) */ 168 struct si_pub pub; /* back plane public state (must be first) */
173 struct bcma_bus *icbus; /* handle to soc interconnect bus */ 169 struct bcma_bus *icbus; /* handle to soc interconnect bus */
174 struct pci_dev *pcibus; /* handle to pci bus */ 170 struct pci_dev *pcibus; /* handle to pci bus */
175 struct pcicore_info *pch; /* PCI/E core handle */
176 struct bcma_device *buscore; 171 struct bcma_device *buscore;
177 struct list_head var_list; /* list of srom variables */
178 172
179 u32 chipst; /* chip status */ 173 u32 chipst; /* chip status */
180}; 174};
@@ -197,38 +191,20 @@ extern u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val);
197extern struct si_pub *ai_attach(struct bcma_bus *pbus); 191extern struct si_pub *ai_attach(struct bcma_bus *pbus);
198extern void ai_detach(struct si_pub *sih); 192extern void ai_detach(struct si_pub *sih);
199extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val); 193extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val);
200extern void ai_pci_setup(struct si_pub *sih, uint coremask);
201extern void ai_clkctl_init(struct si_pub *sih); 194extern void ai_clkctl_init(struct si_pub *sih);
202extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih); 195extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
203extern bool ai_clkctl_cc(struct si_pub *sih, uint mode); 196extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
204extern int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on);
205extern bool ai_deviceremoved(struct si_pub *sih); 197extern bool ai_deviceremoved(struct si_pub *sih);
206extern u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val,
207 u8 priority);
208
209/* OTP status */
210extern bool ai_is_otp_disabled(struct si_pub *sih);
211
212/* SPROM availability */
213extern bool ai_is_sprom_available(struct si_pub *sih);
214 198
215extern void ai_pci_sleep(struct si_pub *sih);
216extern void ai_pci_down(struct si_pub *sih); 199extern void ai_pci_down(struct si_pub *sih);
217extern void ai_pci_up(struct si_pub *sih); 200extern void ai_pci_up(struct si_pub *sih);
218extern int ai_pci_fixcfg(struct si_pub *sih);
219 201
220extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on);
221/* Enable Ex-PA for 4313 */ 202/* Enable Ex-PA for 4313 */
222extern void ai_epa_4313war(struct si_pub *sih); 203extern void ai_epa_4313war(struct si_pub *sih);
223 204
224extern uint ai_get_buscoretype(struct si_pub *sih); 205extern uint ai_get_buscoretype(struct si_pub *sih);
225extern uint ai_get_buscorerev(struct si_pub *sih); 206extern uint ai_get_buscorerev(struct si_pub *sih);
226 207
227static inline int ai_get_ccrev(struct si_pub *sih)
228{
229 return sih->ccrev;
230}
231
232static inline u32 ai_get_cccaps(struct si_pub *sih) 208static inline u32 ai_get_cccaps(struct si_pub *sih)
233{ 209{
234 return sih->cccaps; 210 return sih->cccaps;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
index a47ce25cb9a2..55e12c327911 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
@@ -108,7 +108,7 @@ brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
108struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) 108struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
109{ 109{
110 struct antsel_info *asi; 110 struct antsel_info *asi;
111 struct si_pub *sih = wlc->hw->sih; 111 struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
112 112
113 asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); 113 asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
114 if (!asi) 114 if (!asi)
@@ -118,7 +118,7 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
118 asi->pub = wlc->pub; 118 asi->pub = wlc->pub;
119 asi->antsel_type = ANTSEL_NA; 119 asi->antsel_type = ANTSEL_NA;
120 asi->antsel_avail = false; 120 asi->antsel_avail = false;
121 asi->antsel_antswitch = (u8) getintvar(sih, BRCMS_SROM_ANTSWITCH); 121 asi->antsel_antswitch = sprom->antswitch;
122 122
123 if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) { 123 if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
124 switch (asi->antsel_antswitch) { 124 switch (asi->antsel_antswitch) {
@@ -128,12 +128,12 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
128 /* 4321/2 board with 2x3 switch logic */ 128 /* 4321/2 board with 2x3 switch logic */
129 asi->antsel_type = ANTSEL_2x3; 129 asi->antsel_type = ANTSEL_2x3;
130 /* Antenna selection availability */ 130 /* Antenna selection availability */
131 if (((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) || 131 if ((sprom->ant_available_bg == 7) ||
132 ((u16) getintvar(sih, BRCMS_SROM_AA5G) == 7)) { 132 (sprom->ant_available_a == 7)) {
133 asi->antsel_avail = true; 133 asi->antsel_avail = true;
134 } else if ( 134 } else if (
135 (u16) getintvar(sih, BRCMS_SROM_AA2G) == 3 || 135 sprom->ant_available_bg == 3 ||
136 (u16) getintvar(sih, BRCMS_SROM_AA5G) == 3) { 136 sprom->ant_available_a == 3) {
137 asi->antsel_avail = false; 137 asi->antsel_avail = false;
138 } else { 138 } else {
139 asi->antsel_avail = false; 139 asi->antsel_avail = false;
@@ -146,8 +146,8 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
146 break; 146 break;
147 } 147 }
148 } else if ((asi->pub->sromrev == 4) && 148 } else if ((asi->pub->sromrev == 4) &&
149 ((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) && 149 (sprom->ant_available_bg == 7) &&
150 ((u16) getintvar(sih, BRCMS_SROM_AA5G) == 0)) { 150 (sprom->ant_available_a == 0)) {
151 /* hack to match old 4321CB2 cards with 2of3 antenna switch */ 151 /* hack to match old 4321CB2 cards with 2of3 antenna switch */
152 asi->antsel_type = ANTSEL_2x3; 152 asi->antsel_type = ANTSEL_2x3;
153 asi->antsel_avail = true; 153 asi->antsel_avail = true;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
index 0efe88e25a9a..eb77ac3cfb6b 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+++ b/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)
1110 char country_abbrev[BRCM_CNTRY_BUF_SZ]; 1110 char country_abbrev[BRCM_CNTRY_BUF_SZ];
1111 const struct country_info *country; 1111 const struct country_info *country;
1112 struct brcms_pub *pub = wlc->pub; 1112 struct brcms_pub *pub = wlc->pub;
1113 char *ccode; 1113 struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
1114 1114
1115 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); 1115 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
1116 1116
@@ -1122,9 +1122,8 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
1122 wlc->cmi = wlc_cm; 1122 wlc->cmi = wlc_cm;
1123 1123
1124 /* store the country code for passing up as a regulatory hint */ 1124 /* store the country code for passing up as a regulatory hint */
1125 ccode = getvar(wlc->hw->sih, BRCMS_SROM_CCODE); 1125 if (sprom->alpha2 && brcms_c_country_valid(sprom->alpha2))
1126 if (ccode && brcms_c_country_valid(ccode)) 1126 strncpy(wlc->pub->srom_ccode, sprom->alpha2, sizeof(sprom->alpha2));
1127 strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
1128 1127
1129 /* 1128 /*
1130 * internal country information which must match 1129 * internal country information which must match
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index aa15558f75c8..50f92a0b7c41 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -25,7 +25,6 @@
25#include <linux/bcma/bcma.h> 25#include <linux/bcma/bcma.h>
26#include <net/mac80211.h> 26#include <net/mac80211.h>
27#include <defs.h> 27#include <defs.h>
28#include "nicpci.h"
29#include "phy/phy_int.h" 28#include "phy/phy_int.h"
30#include "d11.h" 29#include "d11.h"
31#include "channel.h" 30#include "channel.h"
@@ -770,7 +769,7 @@ void brcms_dpc(unsigned long data)
770 * Precondition: Since this function is called in brcms_pci_probe() context, 769 * Precondition: Since this function is called in brcms_pci_probe() context,
771 * no locking is required. 770 * no locking is required.
772 */ 771 */
773static int brcms_request_fw(struct brcms_info *wl, struct pci_dev *pdev) 772static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev)
774{ 773{
775 int status; 774 int status;
776 struct device *device = &pdev->dev; 775 struct device *device = &pdev->dev;
@@ -1022,7 +1021,7 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
1022 spin_lock_init(&wl->isr_lock); 1021 spin_lock_init(&wl->isr_lock);
1023 1022
1024 /* prepare ucode */ 1023 /* prepare ucode */
1025 if (brcms_request_fw(wl, pdev->bus->host_pci) < 0) { 1024 if (brcms_request_fw(wl, pdev) < 0) {
1026 wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " 1025 wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
1027 "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); 1026 "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
1028 brcms_release_fw(wl); 1027 brcms_release_fw(wl);
@@ -1043,12 +1042,12 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
1043 wl->pub->ieee_hw = hw; 1042 wl->pub->ieee_hw = hw;
1044 1043
1045 /* register our interrupt handler */ 1044 /* register our interrupt handler */
1046 if (request_irq(pdev->bus->host_pci->irq, brcms_isr, 1045 if (request_irq(pdev->irq, brcms_isr,
1047 IRQF_SHARED, KBUILD_MODNAME, wl)) { 1046 IRQF_SHARED, KBUILD_MODNAME, wl)) {
1048 wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); 1047 wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
1049 goto fail; 1048 goto fail;
1050 } 1049 }
1051 wl->irq = pdev->bus->host_pci->irq; 1050 wl->irq = pdev->irq;
1052 1051
1053 /* register module */ 1052 /* register module */
1054 brcms_c_module_register(wl->pub, "linux", wl, NULL); 1053 brcms_c_module_register(wl->pub, "linux", wl, NULL);
@@ -1098,7 +1097,7 @@ static int __devinit brcms_bcma_probe(struct bcma_device *pdev)
1098 1097
1099 dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n", 1098 dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n",
1100 pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class, 1099 pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class,
1101 pdev->bus->host_pci->irq); 1100 pdev->irq);
1102 1101
1103 if ((pdev->id.manuf != BCMA_MANUF_BCM) || 1102 if ((pdev->id.manuf != BCMA_MANUF_BCM) ||
1104 (pdev->id.id != BCMA_CORE_80211)) 1103 (pdev->id.id != BCMA_CORE_80211))
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index b4d92792c502..19db4052c44c 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -1219,7 +1219,7 @@ static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw)
1219} 1219}
1220 1220
1221/* control chip clock to save power, enable dynamic clock or force fast clock */ 1221/* control chip clock to save power, enable dynamic clock or force fast clock */
1222static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode) 1222static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, enum bcma_clkmode mode)
1223{ 1223{
1224 if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) { 1224 if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) {
1225 /* new chips with PMU, CCS_FORCEHT will distribute the HT clock 1225 /* 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, uint mode)
1229 */ 1229 */
1230 1230
1231 if (wlc_hw->clk) { 1231 if (wlc_hw->clk) {
1232 if (mode == CLK_FAST) { 1232 if (mode == BCMA_CLKMODE_FAST) {
1233 bcma_set32(wlc_hw->d11core, 1233 bcma_set32(wlc_hw->d11core,
1234 D11REGOFFS(clk_ctl_st), 1234 D11REGOFFS(clk_ctl_st),
1235 CCS_FORCEHT); 1235 CCS_FORCEHT);
@@ -1260,7 +1260,7 @@ static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode)
1260 ~CCS_FORCEHT); 1260 ~CCS_FORCEHT);
1261 } 1261 }
1262 } 1262 }
1263 wlc_hw->forcefastclk = (mode == CLK_FAST); 1263 wlc_hw->forcefastclk = (mode == BCMA_CLKMODE_FAST);
1264 } else { 1264 } else {
1265 1265
1266 /* old chips w/o PMU, force HT through cc, 1266 /* 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)
1567 /* request FAST clock if not on */ 1567 /* request FAST clock if not on */
1568 fastclk = wlc_hw->forcefastclk; 1568 fastclk = wlc_hw->forcefastclk;
1569 if (!fastclk) 1569 if (!fastclk)
1570 brcms_b_clkctl_clk(wlc_hw, CLK_FAST); 1570 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
1571 1571
1572 wlc_phy_bw_state_set(wlc_hw->band->pi, bw); 1572 wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
1573 1573
@@ -1576,7 +1576,7 @@ void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw)
1576 1576
1577 /* restore the clk */ 1577 /* restore the clk */
1578 if (!fastclk) 1578 if (!fastclk)
1579 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); 1579 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
1580} 1580}
1581 1581
1582static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw) 1582static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw)
@@ -1882,27 +1882,20 @@ static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw)
1882 return true; 1882 return true;
1883} 1883}
1884 1884
1885static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw) 1885static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ALEN])
1886{ 1886{
1887 enum brcms_srom_id var_id = BRCMS_SROM_MACADDR; 1887 struct ssb_sprom *sprom = &wlc_hw->d11core->bus->sprom;
1888 char *macaddr;
1889 1888
1890 /* If macaddr exists, use it (Sromrev4, CIS, ...). */ 1889 /* If macaddr exists, use it (Sromrev4, CIS, ...). */
1891 macaddr = getvar(wlc_hw->sih, var_id); 1890 if (!is_zero_ether_addr(sprom->il0mac)) {
1892 if (macaddr != NULL) 1891 memcpy(etheraddr, sprom->il0mac, 6);
1893 return macaddr; 1892 return;
1893 }
1894 1894
1895 if (wlc_hw->_nbands > 1) 1895 if (wlc_hw->_nbands > 1)
1896 var_id = BRCMS_SROM_ET1MACADDR; 1896 memcpy(etheraddr, sprom->et1mac, 6);
1897 else 1897 else
1898 var_id = BRCMS_SROM_IL0MACADDR; 1898 memcpy(etheraddr, sprom->il0mac, 6);
1899
1900 macaddr = getvar(wlc_hw->sih, var_id);
1901 if (macaddr == NULL)
1902 wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr "
1903 "getvar(%d) not found\n", wlc_hw->unit, var_id);
1904
1905 return macaddr;
1906} 1899}
1907 1900
1908/* power both the pll and external oscillator on/off */ 1901/* power both the pll and external oscillator on/off */
@@ -1917,9 +1910,6 @@ static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
1917 if (!want && wlc_hw->pllreq) 1910 if (!want && wlc_hw->pllreq)
1918 return; 1911 return;
1919 1912
1920 if (wlc_hw->sih)
1921 ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want);
1922
1923 wlc_hw->sbclk = want; 1913 wlc_hw->sbclk = want;
1924 if (!wlc_hw->sbclk) { 1914 if (!wlc_hw->sbclk) {
1925 wlc_hw->clk = false; 1915 wlc_hw->clk = false;
@@ -2004,7 +1994,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
2004 /* request FAST clock if not on */ 1994 /* request FAST clock if not on */
2005 fastclk = wlc_hw->forcefastclk; 1995 fastclk = wlc_hw->forcefastclk;
2006 if (!fastclk) 1996 if (!fastclk)
2007 brcms_b_clkctl_clk(wlc_hw, CLK_FAST); 1997 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
2008 1998
2009 /* reset the dma engines except first time thru */ 1999 /* reset the dma engines except first time thru */
2010 if (bcma_core_is_enabled(wlc_hw->d11core)) { 2000 if (bcma_core_is_enabled(wlc_hw->d11core)) {
@@ -2053,7 +2043,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
2053 brcms_c_mctrl_reset(wlc_hw); 2043 brcms_c_mctrl_reset(wlc_hw);
2054 2044
2055 if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) 2045 if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU)
2056 brcms_b_clkctl_clk(wlc_hw, CLK_FAST); 2046 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
2057 2047
2058 brcms_b_phy_reset(wlc_hw); 2048 brcms_b_phy_reset(wlc_hw);
2059 2049
@@ -2065,7 +2055,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
2065 2055
2066 /* restore the clk setting */ 2056 /* restore the clk setting */
2067 if (!fastclk) 2057 if (!fastclk)
2068 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); 2058 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
2069} 2059}
2070 2060
2071/* txfifo sizes needs to be modified(increased) since the newer cores 2061/* txfifo sizes needs to be modified(increased) since the newer cores
@@ -2218,7 +2208,7 @@ static void brcms_c_gpio_init(struct brcms_c_info *wlc)
2218 gm |= gc |= BOARD_GPIO_PACTRL; 2208 gm |= gc |= BOARD_GPIO_PACTRL;
2219 2209
2220 /* apply to gpiocontrol register */ 2210 /* apply to gpiocontrol register */
2221 ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); 2211 bcma_chipco_gpio_control(&wlc_hw->d11core->bus->drv_cc, gm, gc);
2222} 2212}
2223 2213
2224static void brcms_ucode_write(struct brcms_hardware *wlc_hw, 2214static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
@@ -3371,7 +3361,7 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) {
3371 /* request FAST clock if not on */ 3361 /* request FAST clock if not on */
3372 fastclk = wlc_hw->forcefastclk; 3362 fastclk = wlc_hw->forcefastclk;
3373 if (!fastclk) 3363 if (!fastclk)
3374 brcms_b_clkctl_clk(wlc_hw, CLK_FAST); 3364 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
3375 3365
3376 /* disable interrupts */ 3366 /* disable interrupts */
3377 macintmask = brcms_intrsoff(wlc->wl); 3367 macintmask = brcms_intrsoff(wlc->wl);
@@ -3405,7 +3395,7 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) {
3405 3395
3406 /* restore the clk */ 3396 /* restore the clk */
3407 if (!fastclk) 3397 if (!fastclk)
3408 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); 3398 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
3409} 3399}
3410 3400
3411static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc, 3401static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
@@ -4436,17 +4426,22 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4436 uint unit, bool piomode) 4426 uint unit, bool piomode)
4437{ 4427{
4438 struct brcms_hardware *wlc_hw; 4428 struct brcms_hardware *wlc_hw;
4439 char *macaddr = NULL;
4440 uint err = 0; 4429 uint err = 0;
4441 uint j; 4430 uint j;
4442 bool wme = false; 4431 bool wme = false;
4443 struct shared_phy_params sha_params; 4432 struct shared_phy_params sha_params;
4444 struct wiphy *wiphy = wlc->wiphy; 4433 struct wiphy *wiphy = wlc->wiphy;
4445 struct pci_dev *pcidev = core->bus->host_pci; 4434 struct pci_dev *pcidev = core->bus->host_pci;
4435 struct ssb_sprom *sprom = &core->bus->sprom;
4446 4436
4447 BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, 4437 if (core->bus->hosttype == BCMA_HOSTTYPE_PCI)
4448 pcidev->vendor, 4438 BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
4449 pcidev->device); 4439 pcidev->vendor,
4440 pcidev->device);
4441 else
4442 BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
4443 core->bus->boardinfo.vendor,
4444 core->bus->boardinfo.type);
4450 4445
4451 wme = true; 4446 wme = true;
4452 4447
@@ -4472,7 +4467,8 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4472 } 4467 }
4473 4468
4474 /* verify again the device is supported */ 4469 /* verify again the device is supported */
4475 if (!brcms_c_chipmatch(pcidev->vendor, pcidev->device)) { 4470 if (core->bus->hosttype == BCMA_HOSTTYPE_PCI &&
4471 !brcms_c_chipmatch(pcidev->vendor, pcidev->device)) {
4476 wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported " 4472 wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported "
4477 "vendor/device (0x%x/0x%x)\n", 4473 "vendor/device (0x%x/0x%x)\n",
4478 unit, pcidev->vendor, pcidev->device); 4474 unit, pcidev->vendor, pcidev->device);
@@ -4480,8 +4476,13 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4480 goto fail; 4476 goto fail;
4481 } 4477 }
4482 4478
4483 wlc_hw->vendorid = pcidev->vendor; 4479 if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
4484 wlc_hw->deviceid = pcidev->device; 4480 wlc_hw->vendorid = pcidev->vendor;
4481 wlc_hw->deviceid = pcidev->device;
4482 } else {
4483 wlc_hw->vendorid = core->bus->boardinfo.vendor;
4484 wlc_hw->deviceid = core->bus->boardinfo.type;
4485 }
4485 4486
4486 wlc_hw->d11core = core; 4487 wlc_hw->d11core = core;
4487 wlc_hw->corerev = core->id.rev; 4488 wlc_hw->corerev = core->id.rev;
@@ -4501,7 +4502,7 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4501 * is still false; But it will be called again inside wlc_corereset, 4502 * is still false; But it will be called again inside wlc_corereset,
4502 * after d11 is out of reset. 4503 * after d11 is out of reset.
4503 */ 4504 */
4504 brcms_b_clkctl_clk(wlc_hw, CLK_FAST); 4505 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
4505 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); 4506 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
4506 4507
4507 if (!brcms_b_validate_chip_access(wlc_hw)) { 4508 if (!brcms_b_validate_chip_access(wlc_hw)) {
@@ -4512,7 +4513,7 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4512 } 4513 }
4513 4514
4514 /* get the board rev, used just below */ 4515 /* get the board rev, used just below */
4515 j = getintvar(wlc_hw->sih, BRCMS_SROM_BOARDREV); 4516 j = sprom->board_rev;
4516 /* promote srom boardrev of 0xFF to 1 */ 4517 /* promote srom boardrev of 0xFF to 1 */
4517 if (j == BOARDREV_PROMOTABLE) 4518 if (j == BOARDREV_PROMOTABLE)
4518 j = BOARDREV_PROMOTED; 4519 j = BOARDREV_PROMOTED;
@@ -4525,11 +4526,9 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4525 err = 15; 4526 err = 15;
4526 goto fail; 4527 goto fail;
4527 } 4528 }
4528 wlc_hw->sromrev = (u8) getintvar(wlc_hw->sih, BRCMS_SROM_REV); 4529 wlc_hw->sromrev = sprom->revision;
4529 wlc_hw->boardflags = (u32) getintvar(wlc_hw->sih, 4530 wlc_hw->boardflags = sprom->boardflags_lo + (sprom->boardflags_hi << 16);
4530 BRCMS_SROM_BOARDFLAGS); 4531 wlc_hw->boardflags2 = sprom->boardflags2_lo + (sprom->boardflags2_hi << 16);
4531 wlc_hw->boardflags2 = (u32) getintvar(wlc_hw->sih,
4532 BRCMS_SROM_BOARDFLAGS2);
4533 4532
4534 if (wlc_hw->boardflags & BFL_NOPLLDOWN) 4533 if (wlc_hw->boardflags & BFL_NOPLLDOWN)
4535 brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED); 4534 brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED);
@@ -4702,25 +4701,18 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4702 */ 4701 */
4703 4702
4704 /* init etheraddr state variables */ 4703 /* init etheraddr state variables */
4705 macaddr = brcms_c_get_macaddr(wlc_hw); 4704 brcms_c_get_macaddr(wlc_hw, wlc_hw->etheraddr);
4706 if (macaddr == NULL) { 4705
4707 wiphy_err(wiphy, "wl%d: brcms_b_attach: macaddr not found\n", 4706 if (is_broadcast_ether_addr(wlc_hw->etheraddr) ||
4708 unit);
4709 err = 21;
4710 goto fail;
4711 }
4712 if (!mac_pton(macaddr, wlc_hw->etheraddr) ||
4713 is_broadcast_ether_addr(wlc_hw->etheraddr) ||
4714 is_zero_ether_addr(wlc_hw->etheraddr)) { 4707 is_zero_ether_addr(wlc_hw->etheraddr)) {
4715 wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr %s\n", 4708 wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr\n",
4716 unit, macaddr); 4709 unit);
4717 err = 22; 4710 err = 22;
4718 goto fail; 4711 goto fail;
4719 } 4712 }
4720 4713
4721 BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", 4714 BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n",
4722 wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih), 4715 wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih));
4723 macaddr);
4724 4716
4725 return err; 4717 return err;
4726 4718
@@ -4770,16 +4762,16 @@ static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
4770 int aa; 4762 int aa;
4771 uint unit; 4763 uint unit;
4772 int bandtype; 4764 int bandtype;
4773 struct si_pub *sih = wlc->hw->sih; 4765 struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
4774 4766
4775 unit = wlc->pub->unit; 4767 unit = wlc->pub->unit;
4776 bandtype = wlc->band->bandtype; 4768 bandtype = wlc->band->bandtype;
4777 4769
4778 /* get antennas available */ 4770 /* get antennas available */
4779 if (bandtype == BRCM_BAND_5G) 4771 if (bandtype == BRCM_BAND_5G)
4780 aa = (s8) getintvar(sih, BRCMS_SROM_AA5G); 4772 aa = sprom->ant_available_a;
4781 else 4773 else
4782 aa = (s8) getintvar(sih, BRCMS_SROM_AA2G); 4774 aa = sprom->ant_available_bg;
4783 4775
4784 if ((aa < 1) || (aa > 15)) { 4776 if ((aa < 1) || (aa > 15)) {
4785 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in" 4777 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
@@ -4799,9 +4791,9 @@ static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
4799 4791
4800 /* Compute Antenna Gain */ 4792 /* Compute Antenna Gain */
4801 if (bandtype == BRCM_BAND_5G) 4793 if (bandtype == BRCM_BAND_5G)
4802 wlc->band->antgain = (s8) getintvar(sih, BRCMS_SROM_AG1); 4794 wlc->band->antgain = sprom->antenna_gain.a1;
4803 else 4795 else
4804 wlc->band->antgain = (s8) getintvar(sih, BRCMS_SROM_AG0); 4796 wlc->band->antgain = sprom->antenna_gain.a0;
4805 4797
4806 brcms_c_attach_antgain_init(wlc); 4798 brcms_c_attach_antgain_init(wlc);
4807 4799
@@ -4952,15 +4944,6 @@ static int brcms_b_detach(struct brcms_c_info *wlc)
4952 4944
4953 callbacks = 0; 4945 callbacks = 0;
4954 4946
4955 if (wlc_hw->sih) {
4956 /*
4957 * detach interrupt sync mechanism since interrupt is disabled
4958 * and per-port interrupt object may has been freed. this must
4959 * be done before sb core switch
4960 */
4961 ai_pci_sleep(wlc_hw->sih);
4962 }
4963
4964 brcms_b_detach_dmapio(wlc_hw); 4947 brcms_b_detach_dmapio(wlc_hw);
4965 4948
4966 band = wlc_hw->band; 4949 band = wlc_hw->band;
@@ -5047,9 +5030,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
5047 */ 5030 */
5048 brcms_b_xtal(wlc_hw, ON); 5031 brcms_b_xtal(wlc_hw, ON);
5049 ai_clkctl_init(wlc_hw->sih); 5032 ai_clkctl_init(wlc_hw->sih);
5050 brcms_b_clkctl_clk(wlc_hw, CLK_FAST); 5033 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
5051
5052 ai_pci_fixcfg(wlc_hw->sih);
5053 5034
5054 /* 5035 /*
5055 * TODO: test suspend/resume 5036 * TODO: test suspend/resume
@@ -5078,8 +5059,6 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
5078 5059
5079static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) 5060static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
5080{ 5061{
5081 uint coremask;
5082
5083 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); 5062 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5084 5063
5085 /* 5064 /*
@@ -5088,15 +5067,14 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
5088 */ 5067 */
5089 brcms_b_xtal(wlc_hw, ON); 5068 brcms_b_xtal(wlc_hw, ON);
5090 ai_clkctl_init(wlc_hw->sih); 5069 ai_clkctl_init(wlc_hw->sih);
5091 brcms_b_clkctl_clk(wlc_hw, CLK_FAST); 5070 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
5092 5071
5093 /* 5072 /*
5094 * Configure pci/pcmcia here instead of in brcms_c_attach() 5073 * Configure pci/pcmcia here instead of in brcms_c_attach()
5095 * to allow mfg hotswap: down, hotswap (chip power cycle), up. 5074 * to allow mfg hotswap: down, hotswap (chip power cycle), up.
5096 */ 5075 */
5097 coremask = (1 << wlc_hw->wlc->core->coreidx); 5076 bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci, wlc_hw->d11core,
5098 5077 true);
5099 ai_pci_setup(wlc_hw->sih, coremask);
5100 5078
5101 /* 5079 /*
5102 * Need to read the hwradio status here to cover the case where the 5080 * Need to read the hwradio status here to cover the case where the
@@ -5126,7 +5104,7 @@ static int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
5126 wlc_phy_hw_state_upd(wlc_hw->band->pi, true); 5104 wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
5127 5105
5128 /* FULLY enable dynamic power control and d11 core interrupt */ 5106 /* FULLY enable dynamic power control and d11 core interrupt */
5129 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); 5107 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
5130 brcms_intrson(wlc_hw->wlc->wl); 5108 brcms_intrson(wlc_hw->wlc->wl);
5131 return 0; 5109 return 0;
5132} 5110}
@@ -5267,7 +5245,7 @@ static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
5267 brcms_intrsoff(wlc_hw->wlc->wl); 5245 brcms_intrsoff(wlc_hw->wlc->wl);
5268 5246
5269 /* ensure we're running on the pll clock again */ 5247 /* ensure we're running on the pll clock again */
5270 brcms_b_clkctl_clk(wlc_hw, CLK_FAST); 5248 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
5271 } 5249 }
5272 /* down phy at the last of this stage */ 5250 /* down phy at the last of this stage */
5273 callbacks += wlc_phy_down(wlc_hw->band->pi); 5251 callbacks += wlc_phy_down(wlc_hw->band->pi);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/nicpci.c b/drivers/net/wireless/brcm80211/brcmsmac/nicpci.c
deleted file mode 100644
index 7fad6dc19258..000000000000
--- a/drivers/net/wireless/brcm80211/brcmsmac/nicpci.c
+++ /dev/null
@@ -1,826 +0,0 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/slab.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20
21#include <defs.h>
22#include <soc.h>
23#include <chipcommon.h>
24#include "aiutils.h"
25#include "pub.h"
26#include "nicpci.h"
27
28/* SPROM offsets */
29#define SRSH_ASPM_OFFSET 4 /* word 4 */
30#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */
31#define SRSH_ASPM_L1_ENB 0x10 /* bit 4 */
32#define SRSH_ASPM_L0s_ENB 0x8 /* bit 3 */
33
34#define SRSH_PCIE_MISC_CONFIG 5 /* word 5 */
35#define SRSH_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */
36#define SRSH_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */
37#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */
38#define SRSH_BD_OFFSET 6 /* word 6 */
39
40/* chipcontrol */
41#define CHIPCTRL_4321_PLL_DOWN 0x800000/* serdes PLL down override */
42
43/* MDIO control */
44#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */
45#define MDIOCTL_DIVISOR_VAL 0x2
46#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */
47#define MDIOCTL_ACCESS_DONE 0x100 /* Transaction complete */
48
49/* MDIO Data */
50#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */
51#define MDIODATA_TA 0x00020000 /* Turnaround */
52
53#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */
54#define MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */
55#define MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */
56#define MDIODATA_DEVADDR_MASK 0x0f800000
57 /* Physmedia devaddr Mask */
58
59/* MDIO Data for older revisions < 10 */
60#define MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift */
61#define MDIODATA_REGADDR_MASK_OLD 0x003c0000
62 /* Regaddr Mask */
63#define MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift */
64#define MDIODATA_DEVADDR_MASK_OLD 0x0fc00000
65 /* Physmedia devaddr Mask */
66
67/* Transactions flags */
68#define MDIODATA_WRITE 0x10000000
69#define MDIODATA_READ 0x20000000
70#define MDIODATA_START 0x40000000
71
72#define MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */
73#define MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */
74
75/* serdes regs (rev < 10) */
76#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */
77#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
78#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
79
80/* SERDES RX registers */
81#define SERDES_RX_CTRL 1 /* Rx cntrl */
82#define SERDES_RX_TIMER1 2 /* Rx Timer1 */
83#define SERDES_RX_CDR 6 /* CDR */
84#define SERDES_RX_CDRBW 7 /* CDR BW */
85/* SERDES RX control register */
86#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */
87#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */
88
89/* SERDES PLL registers */
90#define SERDES_PLL_CTRL 1 /* PLL control reg */
91#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */
92
93/* Linkcontrol reg offset in PCIE Cap */
94#define PCIE_CAP_LINKCTRL_OFFSET 16 /* offset in pcie cap */
95#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */
96#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */
97#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */
98
99#define PCIE_ASPM_ENAB 3 /* ASPM L0s & L1 in linkctrl */
100#define PCIE_ASPM_L1_ENAB 2 /* ASPM L0s & L1 in linkctrl */
101#define PCIE_ASPM_L0s_ENAB 1 /* ASPM L0s & L1 in linkctrl */
102#define PCIE_ASPM_DISAB 0 /* ASPM L0s & L1 in linkctrl */
103
104/* Power management threshold */
105#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */
106#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */
107#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */
108#define PCIE_ASPMTIMER_EXTEND 0x01000000
109 /* > rev7:
110 * enable extend ASPM timer
111 */
112
113/* different register spaces to access thru pcie indirect access */
114#define PCIE_CONFIGREGS 1 /* Access to config space */
115#define PCIE_PCIEREGS 2 /* Access to pcie registers */
116
117/* PCIE protocol PHY diagnostic registers */
118#define PCIE_PLP_STATUSREG 0x204 /* Status */
119
120/* Status reg PCIE_PLP_STATUSREG */
121#define PCIE_PLP_POLARITYINV_STAT 0x10
122
123/* PCIE protocol DLLP diagnostic registers */
124#define PCIE_DLLP_LCREG 0x100 /* Link Control */
125#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */
126
127/* PCIE protocol TLP diagnostic registers */
128#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */
129
130/* Sonics to PCI translation types */
131#define SBTOPCI_PREF 0x4 /* prefetch enable */
132#define SBTOPCI_BURST 0x8 /* burst enable */
133#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */
134
135#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */
136
137/* PCI core index in SROM shadow area */
138#define SRSH_PI_OFFSET 0 /* first word */
139#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
140#define SRSH_PI_SHIFT 12 /* bit 15:12 */
141
142#define PCIREGOFFS(field) offsetof(struct sbpciregs, field)
143#define PCIEREGOFFS(field) offsetof(struct sbpcieregs, field)
144
145/* Sonics side: PCI core and host control registers */
146struct sbpciregs {
147 u32 control; /* PCI control */
148 u32 PAD[3];
149 u32 arbcontrol; /* PCI arbiter control */
150 u32 clkrun; /* Clkrun Control (>=rev11) */
151 u32 PAD[2];
152 u32 intstatus; /* Interrupt status */
153 u32 intmask; /* Interrupt mask */
154 u32 sbtopcimailbox; /* Sonics to PCI mailbox */
155 u32 PAD[9];
156 u32 bcastaddr; /* Sonics broadcast address */
157 u32 bcastdata; /* Sonics broadcast data */
158 u32 PAD[2];
159 u32 gpioin; /* ro: gpio input (>=rev2) */
160 u32 gpioout; /* rw: gpio output (>=rev2) */
161 u32 gpioouten; /* rw: gpio output enable (>= rev2) */
162 u32 gpiocontrol; /* rw: gpio control (>= rev2) */
163 u32 PAD[36];
164 u32 sbtopci0; /* Sonics to PCI translation 0 */
165 u32 sbtopci1; /* Sonics to PCI translation 1 */
166 u32 sbtopci2; /* Sonics to PCI translation 2 */
167 u32 PAD[189];
168 u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
169 u16 sprom[36]; /* SPROM shadow Area */
170 u32 PAD[46];
171};
172
173/* SB side: PCIE core and host control registers */
174struct sbpcieregs {
175 u32 control; /* host mode only */
176 u32 PAD[2];
177 u32 biststatus; /* bist Status: 0x00C */
178 u32 gpiosel; /* PCIE gpio sel: 0x010 */
179 u32 gpioouten; /* PCIE gpio outen: 0x14 */
180 u32 PAD[2];
181 u32 intstatus; /* Interrupt status: 0x20 */
182 u32 intmask; /* Interrupt mask: 0x24 */
183 u32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */
184 u32 PAD[53];
185 u32 sbtopcie0; /* sb to pcie translation 0: 0x100 */
186 u32 sbtopcie1; /* sb to pcie translation 1: 0x104 */
187 u32 sbtopcie2; /* sb to pcie translation 2: 0x108 */
188 u32 PAD[5];
189
190 /* pcie core supports in direct access to config space */
191 u32 configaddr; /* pcie config space access: Address field: 0x120 */
192 u32 configdata; /* pcie config space access: Data field: 0x124 */
193
194 /* mdio access to serdes */
195 u32 mdiocontrol; /* controls the mdio access: 0x128 */
196 u32 mdiodata; /* Data to the mdio access: 0x12c */
197
198 /* pcie protocol phy/dllp/tlp register indirect access mechanism */
199 u32 pcieindaddr; /* indirect access to
200 * the internal register: 0x130
201 */
202 u32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */
203
204 u32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */
205 u32 PAD[177];
206 u32 pciecfg[4][64]; /* 0x400 - 0x7FF, PCIE Cfg Space */
207 u16 sprom[64]; /* SPROM shadow Area */
208};
209
210struct pcicore_info {
211 struct bcma_device *core;
212 struct si_pub *sih; /* System interconnect handle */
213 struct pci_dev *dev;
214 u8 pciecap_lcreg_offset;/* PCIE capability LCreg offset
215 * in the config space
216 */
217 bool pcie_pr42767;
218 u8 pcie_polarity;
219 u8 pcie_war_aspm_ovr; /* Override ASPM/Clkreq settings */
220
221 u8 pmecap_offset; /* PM Capability offset in the config space */
222 bool pmecap; /* Capable of generating PME */
223};
224
225#define PCIE_ASPM(sih) \
226 ((ai_get_buscoretype(sih) == PCIE_CORE_ID) && \
227 ((ai_get_buscorerev(sih) >= 3) && \
228 (ai_get_buscorerev(sih) <= 5)))
229
230
231/* delay needed between the mdio control/ mdiodata register data access */
232static void pr28829_delay(void)
233{
234 udelay(10);
235}
236
237/* Initialize the PCI core.
238 * It's caller's responsibility to make sure that this is done only once
239 */
240struct pcicore_info *pcicore_init(struct si_pub *sih, struct bcma_device *core)
241{
242 struct pcicore_info *pi;
243
244 /* alloc struct pcicore_info */
245 pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC);
246 if (pi == NULL)
247 return NULL;
248
249 pi->sih = sih;
250 pi->dev = core->bus->host_pci;
251 pi->core = core;
252
253 if (core->id.id == PCIE_CORE_ID) {
254 u8 cap_ptr;
255 cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
256 NULL, NULL);
257 pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
258 }
259 return pi;
260}
261
262void pcicore_deinit(struct pcicore_info *pch)
263{
264 kfree(pch);
265}
266
267/* return cap_offset if requested capability exists in the PCI config space */
268/* Note that it's caller's responsibility to make sure it's a pci bus */
269u8
270pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
271 unsigned char *buf, u32 *buflen)
272{
273 u8 cap_id;
274 u8 cap_ptr = 0;
275 u32 bufsize;
276 u8 byte_val;
277
278 /* check for Header type 0 */
279 pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
280 if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
281 goto end;
282
283 /* check if the capability pointer field exists */
284 pci_read_config_byte(dev, PCI_STATUS, &byte_val);
285 if (!(byte_val & PCI_STATUS_CAP_LIST))
286 goto end;
287
288 pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
289 /* check if the capability pointer is 0x00 */
290 if (cap_ptr == 0x00)
291 goto end;
292
293 /* loop thru the capability list
294 * and see if the pcie capability exists
295 */
296
297 pci_read_config_byte(dev, cap_ptr, &cap_id);
298
299 while (cap_id != req_cap_id) {
300 pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
301 if (cap_ptr == 0x00)
302 break;
303 pci_read_config_byte(dev, cap_ptr, &cap_id);
304 }
305 if (cap_id != req_cap_id)
306 goto end;
307
308 /* found the caller requested capability */
309 if (buf != NULL && buflen != NULL) {
310 u8 cap_data;
311
312 bufsize = *buflen;
313 if (!bufsize)
314 goto end;
315 *buflen = 0;
316 /* copy the capability data excluding cap ID and next ptr */
317 cap_data = cap_ptr + 2;
318 if ((bufsize + cap_data) > PCI_SZPCR)
319 bufsize = PCI_SZPCR - cap_data;
320 *buflen = bufsize;
321 while (bufsize--) {
322 pci_read_config_byte(dev, cap_data, buf);
323 cap_data++;
324 buf++;
325 }
326 }
327end:
328 return cap_ptr;
329}
330
331/* ***** Register Access API */
332static uint
333pcie_readreg(struct bcma_device *core, uint addrtype, uint offset)
334{
335 uint retval = 0xFFFFFFFF;
336
337 switch (addrtype) {
338 case PCIE_CONFIGREGS:
339 bcma_write32(core, PCIEREGOFFS(configaddr), offset);
340 (void)bcma_read32(core, PCIEREGOFFS(configaddr));
341 retval = bcma_read32(core, PCIEREGOFFS(configdata));
342 break;
343 case PCIE_PCIEREGS:
344 bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
345 (void)bcma_read32(core, PCIEREGOFFS(pcieindaddr));
346 retval = bcma_read32(core, PCIEREGOFFS(pcieinddata));
347 break;
348 }
349
350 return retval;
351}
352
353static uint pcie_writereg(struct bcma_device *core, uint addrtype,
354 uint offset, uint val)
355{
356 switch (addrtype) {
357 case PCIE_CONFIGREGS:
358 bcma_write32(core, PCIEREGOFFS(configaddr), offset);
359 bcma_write32(core, PCIEREGOFFS(configdata), val);
360 break;
361 case PCIE_PCIEREGS:
362 bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
363 bcma_write32(core, PCIEREGOFFS(pcieinddata), val);
364 break;
365 default:
366 break;
367 }
368 return 0;
369}
370
371static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
372{
373 uint mdiodata, i = 0;
374 uint pcie_serdes_spinwait = 200;
375
376 mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
377 (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
378 (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
379 (blk << 4));
380 bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);
381
382 pr28829_delay();
383 /* retry till the transaction is complete */
384 while (i < pcie_serdes_spinwait) {
385 if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
386 MDIOCTL_ACCESS_DONE)
387 break;
388
389 udelay(1000);
390 i++;
391 }
392
393 if (i >= pcie_serdes_spinwait)
394 return false;
395
396 return true;
397}
398
399static int
400pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
401 uint *val)
402{
403 uint mdiodata;
404 uint i = 0;
405 uint pcie_serdes_spinwait = 10;
406
407 /* enable mdio access to SERDES */
408 bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol),
409 MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
410
411 if (ai_get_buscorerev(pi->sih) >= 10) {
412 /* new serdes is slower in rw,
413 * using two layers of reg address mapping
414 */
415 if (!pcie_mdiosetblock(pi, physmedia))
416 return 1;
417 mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
418 (regaddr << MDIODATA_REGADDR_SHF));
419 pcie_serdes_spinwait *= 20;
420 } else {
421 mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) |
422 (regaddr << MDIODATA_REGADDR_SHF_OLD));
423 }
424
425 if (!write)
426 mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
427 else
428 mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
429 *val);
430
431 bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);
432
433 pr28829_delay();
434
435 /* retry till the transaction is complete */
436 while (i < pcie_serdes_spinwait) {
437 if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
438 MDIOCTL_ACCESS_DONE) {
439 if (!write) {
440 pr28829_delay();
441 *val = (bcma_read32(pi->core,
442 PCIEREGOFFS(mdiodata)) &
443 MDIODATA_MASK);
444 }
445 /* Disable mdio access to SERDES */
446 bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
447 return 0;
448 }
449 udelay(1000);
450 i++;
451 }
452
453 /* Timed out. Disable mdio access to SERDES. */
454 bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
455 return 1;
456}
457
458/* use the mdio interface to read from mdio slaves */
459static int
460pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint regaddr,
461 uint *regval)
462{
463 return pcie_mdioop(pi, physmedia, regaddr, false, regval);
464}
465
466/* use the mdio interface to write to mdio slaves */
467static int
468pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val)
469{
470 return pcie_mdioop(pi, physmedia, regaddr, true, &val);
471}
472
473/* ***** Support functions ***** */
474static u8 pcie_clkreq(struct pcicore_info *pi, u32 mask, u32 val)
475{
476 u32 reg_val;
477 u8 offset;
478
479 offset = pi->pciecap_lcreg_offset;
480 if (!offset)
481 return 0;
482
483 pci_read_config_dword(pi->dev, offset, &reg_val);
484 /* set operation */
485 if (mask) {
486 if (val)
487 reg_val |= PCIE_CLKREQ_ENAB;
488 else
489 reg_val &= ~PCIE_CLKREQ_ENAB;
490 pci_write_config_dword(pi->dev, offset, reg_val);
491 pci_read_config_dword(pi->dev, offset, &reg_val);
492 }
493 if (reg_val & PCIE_CLKREQ_ENAB)
494 return 1;
495 else
496 return 0;
497}
498
499static void pcie_extendL1timer(struct pcicore_info *pi, bool extend)
500{
501 u32 w;
502 struct si_pub *sih = pi->sih;
503
504 if (ai_get_buscoretype(sih) != PCIE_CORE_ID ||
505 ai_get_buscorerev(sih) < 7)
506 return;
507
508 w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
509 if (extend)
510 w |= PCIE_ASPMTIMER_EXTEND;
511 else
512 w &= ~PCIE_ASPMTIMER_EXTEND;
513 pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
514 w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
515}
516
517/* centralized clkreq control policy */
518static void pcie_clkreq_upd(struct pcicore_info *pi, uint state)
519{
520 struct si_pub *sih = pi->sih;
521
522 switch (state) {
523 case SI_DOATTACH:
524 if (PCIE_ASPM(sih))
525 pcie_clkreq(pi, 1, 0);
526 break;
527 case SI_PCIDOWN:
528 /* turn on serdes PLL down */
529 if (ai_get_buscorerev(sih) == 6) {
530 ai_cc_reg(sih,
531 offsetof(struct chipcregs, chipcontrol_addr),
532 ~0, 0);
533 ai_cc_reg(sih,
534 offsetof(struct chipcregs, chipcontrol_data),
535 ~0x40, 0);
536 } else if (pi->pcie_pr42767) {
537 pcie_clkreq(pi, 1, 1);
538 }
539 break;
540 case SI_PCIUP:
541 /* turn off serdes PLL down */
542 if (ai_get_buscorerev(sih) == 6) {
543 ai_cc_reg(sih,
544 offsetof(struct chipcregs, chipcontrol_addr),
545 ~0, 0);
546 ai_cc_reg(sih,
547 offsetof(struct chipcregs, chipcontrol_data),
548 ~0x40, 0x40);
549 } else if (PCIE_ASPM(sih)) { /* disable clkreq */
550 pcie_clkreq(pi, 1, 0);
551 }
552 break;
553 }
554}
555
556/* ***** PCI core WARs ***** */
557/* Done only once at attach time */
558static void pcie_war_polarity(struct pcicore_info *pi)
559{
560 u32 w;
561
562 if (pi->pcie_polarity != 0)
563 return;
564
565 w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
566
567 /* Detect the current polarity at attach and force that polarity and
568 * disable changing the polarity
569 */
570 if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
571 pi->pcie_polarity = SERDES_RX_CTRL_FORCE;
572 else
573 pi->pcie_polarity = (SERDES_RX_CTRL_FORCE |
574 SERDES_RX_CTRL_POLARITY);
575}
576
577/* enable ASPM and CLKREQ if srom doesn't have it */
578/* Needs to happen when update to shadow SROM is needed
579 * : Coming out of 'standby'/'hibernate'
580 * : If pcie_war_aspm_ovr state changed
581 */
582static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
583{
584 struct si_pub *sih = pi->sih;
585 u16 val16;
586 u32 w;
587
588 if (!PCIE_ASPM(sih))
589 return;
590
591 /* bypass this on QT or VSIM */
592 val16 = bcma_read16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET]));
593
594 val16 &= ~SRSH_ASPM_ENB;
595 if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
596 val16 |= SRSH_ASPM_ENB;
597 else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
598 val16 |= SRSH_ASPM_L1_ENB;
599 else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
600 val16 |= SRSH_ASPM_L0s_ENB;
601
602 bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET]), val16);
603
604 pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
605 w &= ~PCIE_ASPM_ENAB;
606 w |= pi->pcie_war_aspm_ovr;
607 pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
608
609 val16 = bcma_read16(pi->core,
610 PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5]));
611
612 if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
613 val16 |= SRSH_CLKREQ_ENB;
614 pi->pcie_pr42767 = true;
615 } else
616 val16 &= ~SRSH_CLKREQ_ENB;
617
618 bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5]),
619 val16);
620}
621
622/* Apply the polarity determined at the start */
623/* Needs to happen when coming out of 'standby'/'hibernate' */
624static void pcie_war_serdes(struct pcicore_info *pi)
625{
626 u32 w = 0;
627
628 if (pi->pcie_polarity != 0)
629 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
630 pi->pcie_polarity);
631
632 pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
633 if (w & PLL_CTRL_FREQDET_EN) {
634 w &= ~PLL_CTRL_FREQDET_EN;
635 pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
636 }
637}
638
639/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
640/* Needs to happen when coming out of 'standby'/'hibernate' */
641static void pcie_misc_config_fixup(struct pcicore_info *pi)
642{
643 u16 val16;
644
645 val16 = bcma_read16(pi->core,
646 PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG]));
647
648 if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
649 val16 |= SRSH_L23READY_EXIT_NOPERST;
650 bcma_write16(pi->core,
651 PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG]), val16);
652 }
653}
654
655/* quick hack for testing */
656/* Needs to happen when coming out of 'standby'/'hibernate' */
657static void pcie_war_noplldown(struct pcicore_info *pi)
658{
659 /* turn off serdes PLL down */
660 ai_cc_reg(pi->sih, offsetof(struct chipcregs, chipcontrol),
661 CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
662
663 /* clear srom shadow backdoor */
664 bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_BD_OFFSET]), 0);
665}
666
667/* Needs to happen when coming out of 'standby'/'hibernate' */
668static void pcie_war_pci_setup(struct pcicore_info *pi)
669{
670 struct si_pub *sih = pi->sih;
671 u32 w;
672
673 if (ai_get_buscorerev(sih) == 0 || ai_get_buscorerev(sih) == 1) {
674 w = pcie_readreg(pi->core, PCIE_PCIEREGS,
675 PCIE_TLP_WORKAROUNDSREG);
676 w |= 0x8;
677 pcie_writereg(pi->core, PCIE_PCIEREGS,
678 PCIE_TLP_WORKAROUNDSREG, w);
679 }
680
681 if (ai_get_buscorerev(sih) == 1) {
682 w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
683 w |= 0x40;
684 pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
685 }
686
687 if (ai_get_buscorerev(sih) == 0) {
688 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
689 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
690 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
691 } else if (PCIE_ASPM(sih)) {
692 /* Change the L1 threshold for better performance */
693 w = pcie_readreg(pi->core, PCIE_PCIEREGS,
694 PCIE_DLLP_PMTHRESHREG);
695 w &= ~PCIE_L1THRESHOLDTIME_MASK;
696 w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT;
697 pcie_writereg(pi->core, PCIE_PCIEREGS,
698 PCIE_DLLP_PMTHRESHREG, w);
699
700 pcie_war_serdes(pi);
701
702 pcie_war_aspm_clkreq(pi);
703 } else if (ai_get_buscorerev(pi->sih) == 7)
704 pcie_war_noplldown(pi);
705
706 /* Note that the fix is actually in the SROM,
707 * that's why this is open-ended
708 */
709 if (ai_get_buscorerev(pi->sih) >= 6)
710 pcie_misc_config_fixup(pi);
711}
712
713/* ***** Functions called during driver state changes ***** */
714void pcicore_attach(struct pcicore_info *pi, int state)
715{
716 struct si_pub *sih = pi->sih;
717 u32 bfl2 = (u32)getintvar(sih, BRCMS_SROM_BOARDFLAGS2);
718
719 /* Determine if this board needs override */
720 if (PCIE_ASPM(sih)) {
721 if (bfl2 & BFL2_PCIEWAR_OVR)
722 pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
723 else
724 pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
725 }
726
727 /* These need to happen in this order only */
728 pcie_war_polarity(pi);
729
730 pcie_war_serdes(pi);
731
732 pcie_war_aspm_clkreq(pi);
733
734 pcie_clkreq_upd(pi, state);
735
736}
737
738void pcicore_hwup(struct pcicore_info *pi)
739{
740 if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
741 return;
742
743 pcie_war_pci_setup(pi);
744}
745
746void pcicore_up(struct pcicore_info *pi, int state)
747{
748 if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
749 return;
750
751 /* Restore L1 timer for better performance */
752 pcie_extendL1timer(pi, true);
753
754 pcie_clkreq_upd(pi, state);
755}
756
757/* When the device is going to enter D3 state
758 * (or the system is going to enter S3/S4 states)
759 */
760void pcicore_sleep(struct pcicore_info *pi)
761{
762 u32 w;
763
764 if (!pi || !PCIE_ASPM(pi->sih))
765 return;
766
767 pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
768 w &= ~PCIE_CAP_LCREG_ASPML1;
769 pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
770
771 pi->pcie_pr42767 = false;
772}
773
774void pcicore_down(struct pcicore_info *pi, int state)
775{
776 if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
777 return;
778
779 pcie_clkreq_upd(pi, state);
780
781 /* Reduce L1 timer for better power savings */
782 pcie_extendL1timer(pi, false);
783}
784
785void pcicore_fixcfg(struct pcicore_info *pi)
786{
787 struct bcma_device *core = pi->core;
788 u16 val16;
789 uint regoff;
790
791 switch (pi->core->id.id) {
792 case BCMA_CORE_PCI:
793 regoff = PCIREGOFFS(sprom[SRSH_PI_OFFSET]);
794 break;
795
796 case BCMA_CORE_PCIE:
797 regoff = PCIEREGOFFS(sprom[SRSH_PI_OFFSET]);
798 break;
799
800 default:
801 return;
802 }
803
804 val16 = bcma_read16(pi->core, regoff);
805 if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) !=
806 (u16)core->core_index) {
807 val16 = ((u16)core->core_index << SRSH_PI_SHIFT) |
808 (val16 & ~SRSH_PI_MASK);
809 bcma_write16(pi->core, regoff, val16);
810 }
811}
812
813/* precondition: current core is pci core */
814void
815pcicore_pci_setup(struct pcicore_info *pi)
816{
817 bcma_set32(pi->core, PCIREGOFFS(sbtopci2),
818 SBTOPCI_PREF | SBTOPCI_BURST);
819
820 if (pi->core->id.rev >= 11) {
821 bcma_set32(pi->core, PCIREGOFFS(sbtopci2),
822 SBTOPCI_RC_READMULTI);
823 bcma_set32(pi->core, PCIREGOFFS(clkrun), PCI_CLKRUN_DSBL);
824 (void)bcma_read32(pi->core, PCIREGOFFS(clkrun));
825 }
826}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/nicpci.h b/drivers/net/wireless/brcm80211/brcmsmac/nicpci.h
deleted file mode 100644
index 9fc3ead540a8..000000000000
--- a/drivers/net/wireless/brcm80211/brcmsmac/nicpci.h
+++ /dev/null
@@ -1,77 +0,0 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_NICPCI_H_
18#define _BRCM_NICPCI_H_
19
20#include "types.h"
21
22/* PCI configuration address space size */
23#define PCI_SZPCR 256
24
25/* Brcm PCI configuration registers */
26/* backplane address space accessed by BAR0 */
27#define PCI_BAR0_WIN 0x80
28/* sprom property control */
29#define PCI_SPROM_CONTROL 0x88
30/* mask of PCI and other cores interrupts */
31#define PCI_INT_MASK 0x94
32/* backplane core interrupt mask bits offset */
33#define PCI_SBIM_SHIFT 8
34/* backplane address space accessed by second 4KB of BAR0 */
35#define PCI_BAR0_WIN2 0xac
36/* pci config space gpio input (>=rev3) */
37#define PCI_GPIO_IN 0xb0
38/* pci config space gpio output (>=rev3) */
39#define PCI_GPIO_OUT 0xb4
40/* pci config space gpio output enable (>=rev3) */
41#define PCI_GPIO_OUTEN 0xb8
42
43/* bar0 + 4K accesses external sprom */
44#define PCI_BAR0_SPROM_OFFSET (4 * 1024)
45/* bar0 + 6K accesses pci core registers */
46#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024)
47/*
48 * pci core SB registers are at the end of the
49 * 8KB window, so their address is the "regular"
50 * address plus 4K
51 */
52#define PCI_BAR0_PCISBR_OFFSET (4 * 1024)
53/* bar0 window size Match with corerev 13 */
54#define PCI_BAR0_WINSZ (16 * 1024)
55/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
56/* bar0 + 8K accesses pci/pcie core registers */
57#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024)
58/* bar0 + 12K accesses chipc core registers */
59#define PCI_16KB0_CCREGS_OFFSET (12 * 1024)
60
61struct sbpciregs;
62struct sbpcieregs;
63
64extern struct pcicore_info *pcicore_init(struct si_pub *sih,
65 struct bcma_device *core);
66extern void pcicore_deinit(struct pcicore_info *pch);
67extern void pcicore_attach(struct pcicore_info *pch, int state);
68extern void pcicore_hwup(struct pcicore_info *pch);
69extern void pcicore_up(struct pcicore_info *pch, int state);
70extern void pcicore_sleep(struct pcicore_info *pch);
71extern void pcicore_down(struct pcicore_info *pch, int state);
72extern u8 pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
73 unsigned char *buf, u32 *buflen);
74extern void pcicore_fixcfg(struct pcicore_info *pch);
75extern void pcicore_pci_setup(struct pcicore_info *pch);
76
77#endif /* _BRCM_NICPCI_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/otp.c b/drivers/net/wireless/brcm80211/brcmsmac/otp.c
deleted file mode 100644
index f1ca12625860..000000000000
--- a/drivers/net/wireless/brcm80211/brcmsmac/otp.c
+++ /dev/null
@@ -1,410 +0,0 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/io.h>
18#include <linux/errno.h>
19#include <linux/string.h>
20
21#include <brcm_hw_ids.h>
22#include <chipcommon.h>
23#include "aiutils.h"
24#include "otp.h"
25
26#define OTPS_GUP_MASK 0x00000f00
27#define OTPS_GUP_SHIFT 8
28/* h/w subregion is programmed */
29#define OTPS_GUP_HW 0x00000100
30/* s/w subregion is programmed */
31#define OTPS_GUP_SW 0x00000200
32/* chipid/pkgopt subregion is programmed */
33#define OTPS_GUP_CI 0x00000400
34/* fuse subregion is programmed */
35#define OTPS_GUP_FUSE 0x00000800
36
37/* Fields in otpprog in rev >= 21 */
38#define OTPP_COL_MASK 0x000000ff
39#define OTPP_COL_SHIFT 0
40#define OTPP_ROW_MASK 0x0000ff00
41#define OTPP_ROW_SHIFT 8
42#define OTPP_OC_MASK 0x0f000000
43#define OTPP_OC_SHIFT 24
44#define OTPP_READERR 0x10000000
45#define OTPP_VALUE_MASK 0x20000000
46#define OTPP_VALUE_SHIFT 29
47#define OTPP_START_BUSY 0x80000000
48#define OTPP_READ 0x40000000
49
50/* Opcodes for OTPP_OC field */
51#define OTPPOC_READ 0
52#define OTPPOC_BIT_PROG 1
53#define OTPPOC_VERIFY 3
54#define OTPPOC_INIT 4
55#define OTPPOC_SET 5
56#define OTPPOC_RESET 6
57#define OTPPOC_OCST 7
58#define OTPPOC_ROW_LOCK 8
59#define OTPPOC_PRESCN_TEST 9
60
61#define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23)
62
63#define OTPP_TRIES 10000000 /* # of tries for OTPP */
64
65#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */
66
67/* Fixed size subregions sizes in words */
68#define OTPGU_CI_SZ 2
69
70struct otpinfo;
71
72/* OTP function struct */
73struct otp_fn_s {
74 int (*init)(struct si_pub *sih, struct otpinfo *oi);
75 int (*read_region)(struct otpinfo *oi, int region, u16 *data,
76 uint *wlen);
77};
78
79struct otpinfo {
80 struct bcma_device *core; /* chipc core */
81 const struct otp_fn_s *fn; /* OTP functions */
82 struct si_pub *sih; /* Saved sb handle */
83
84 /* IPX OTP section */
85 u16 wsize; /* Size of otp in words */
86 u16 rows; /* Geometry */
87 u16 cols; /* Geometry */
88 u32 status; /* Flag bits (lock/prog/rv).
89 * (Reflected only when OTP is power cycled)
90 */
91 u16 hwbase; /* hardware subregion offset */
92 u16 hwlim; /* hardware subregion boundary */
93 u16 swbase; /* software subregion offset */
94 u16 swlim; /* software subregion boundary */
95 u16 fbase; /* fuse subregion offset */
96 u16 flim; /* fuse subregion boundary */
97 int otpgu_base; /* offset to General Use Region */
98};
99
100/* OTP layout */
101/* CC revs 21, 24 and 27 OTP General Use Region word offset */
102#define REVA4_OTPGU_BASE 12
103
104/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
105#define REVB8_OTPGU_BASE 20
106
107/* CC rev 36 OTP General Use Region word offset */
108#define REV36_OTPGU_BASE 12
109
110/* Subregion word offsets in General Use region */
111#define OTPGU_HSB_OFF 0
112#define OTPGU_SFB_OFF 1
113#define OTPGU_CI_OFF 2
114#define OTPGU_P_OFF 3
115#define OTPGU_SROM_OFF 4
116
117/* Flag bit offsets in General Use region */
118#define OTPGU_HWP_OFF 60
119#define OTPGU_SWP_OFF 61
120#define OTPGU_CIP_OFF 62
121#define OTPGU_FUSEP_OFF 63
122#define OTPGU_CIP_MSK 0x4000
123#define OTPGU_P_MSK 0xf000
124#define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16)
125
126/* OTP Size */
127#define OTP_SZ_FU_324 ((roundup(324, 8))/8) /* 324 bits */
128#define OTP_SZ_FU_288 (288/8) /* 288 bits */
129#define OTP_SZ_FU_216 (216/8) /* 216 bits */
130#define OTP_SZ_FU_72 (72/8) /* 72 bits */
131#define OTP_SZ_CHECKSUM (16/8) /* 16 bits */
132#define OTP4315_SWREG_SZ 178 /* 178 bytes */
133#define OTP_SZ_FU_144 (144/8) /* 144 bits */
134
135static u16
136ipxotp_otpr(struct otpinfo *oi, uint wn)
137{
138 return bcma_read16(oi->core,
139 CHIPCREGOFFS(sromotp[wn]));
140}
141
142/*
143 * Calculate max HW/SW region byte size by subtracting fuse region
144 * and checksum size, osizew is oi->wsize (OTP size - GU size) in words
145 */
146static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew)
147{
148 int ret = 0;
149
150 switch (ai_get_chip_id(sih)) {
151 case BCM43224_CHIP_ID:
152 case BCM43225_CHIP_ID:
153 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
154 break;
155 case BCM4313_CHIP_ID:
156 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
157 break;
158 default:
159 break; /* Don't know about this chip */
160 }
161
162 return ret;
163}
164
165static void _ipxotp_init(struct otpinfo *oi)
166{
167 uint k;
168 u32 otpp, st;
169 int ccrev = ai_get_ccrev(oi->sih);
170
171
172 /*
173 * record word offset of General Use Region
174 * for various chipcommon revs
175 */
176 if (ccrev == 21 || ccrev == 24
177 || ccrev == 27) {
178 oi->otpgu_base = REVA4_OTPGU_BASE;
179 } else if (ccrev == 36) {
180 /*
181 * OTP size greater than equal to 2KB (128 words),
182 * otpgu_base is similar to rev23
183 */
184 if (oi->wsize >= 128)
185 oi->otpgu_base = REVB8_OTPGU_BASE;
186 else
187 oi->otpgu_base = REV36_OTPGU_BASE;
188 } else if (ccrev == 23 || ccrev >= 25) {
189 oi->otpgu_base = REVB8_OTPGU_BASE;
190 }
191
192 /* First issue an init command so the status is up to date */
193 otpp =
194 OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
195
196 bcma_write32(oi->core, CHIPCREGOFFS(otpprog), otpp);
197 st = bcma_read32(oi->core, CHIPCREGOFFS(otpprog));
198 for (k = 0; (st & OTPP_START_BUSY) && (k < OTPP_TRIES); k++)
199 st = bcma_read32(oi->core, CHIPCREGOFFS(otpprog));
200 if (k >= OTPP_TRIES)
201 return;
202
203 /* Read OTP lock bits and subregion programmed indication bits */
204 oi->status = bcma_read32(oi->core, CHIPCREGOFFS(otpstatus));
205
206 if ((ai_get_chip_id(oi->sih) == BCM43224_CHIP_ID)
207 || (ai_get_chip_id(oi->sih) == BCM43225_CHIP_ID)) {
208 u32 p_bits;
209 p_bits = (ipxotp_otpr(oi, oi->otpgu_base + OTPGU_P_OFF) &
210 OTPGU_P_MSK) >> OTPGU_P_SHIFT;
211 oi->status |= (p_bits << OTPS_GUP_SHIFT);
212 }
213
214 /*
215 * h/w region base and fuse region limit are fixed to
216 * the top and the bottom of the general use region.
217 * Everything else can be flexible.
218 */
219 oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
220 oi->hwlim = oi->wsize;
221 if (oi->status & OTPS_GUP_HW) {
222 oi->hwlim =
223 ipxotp_otpr(oi, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
224 oi->swbase = oi->hwlim;
225 } else
226 oi->swbase = oi->hwbase;
227
228 /* subtract fuse and checksum from beginning */
229 oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
230
231 if (oi->status & OTPS_GUP_SW) {
232 oi->swlim =
233 ipxotp_otpr(oi, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
234 oi->fbase = oi->swlim;
235 } else
236 oi->fbase = oi->swbase;
237
238 oi->flim = oi->wsize;
239}
240
241static int ipxotp_init(struct si_pub *sih, struct otpinfo *oi)
242{
243 /* Make sure we're running IPX OTP */
244 if (!OTPTYPE_IPX(ai_get_ccrev(sih)))
245 return -EBADE;
246
247 /* Make sure OTP is not disabled */
248 if (ai_is_otp_disabled(sih))
249 return -EBADE;
250
251 /* Check for otp size */
252 switch ((ai_get_cccaps(sih) & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
253 case 0:
254 /* Nothing there */
255 return -EBADE;
256 case 1: /* 32x64 */
257 oi->rows = 32;
258 oi->cols = 64;
259 oi->wsize = 128;
260 break;
261 case 2: /* 64x64 */
262 oi->rows = 64;
263 oi->cols = 64;
264 oi->wsize = 256;
265 break;
266 case 5: /* 96x64 */
267 oi->rows = 96;
268 oi->cols = 64;
269 oi->wsize = 384;
270 break;
271 case 7: /* 16x64 *//* 1024 bits */
272 oi->rows = 16;
273 oi->cols = 64;
274 oi->wsize = 64;
275 break;
276 default:
277 /* Don't know the geometry */
278 return -EBADE;
279 }
280
281 /* Retrieve OTP region info */
282 _ipxotp_init(oi);
283 return 0;
284}
285
286static int
287ipxotp_read_region(struct otpinfo *oi, int region, u16 *data, uint *wlen)
288{
289 uint base, i, sz;
290
291 /* Validate region selection */
292 switch (region) {
293 case OTP_HW_RGN:
294 sz = (uint) oi->hwlim - oi->hwbase;
295 if (!(oi->status & OTPS_GUP_HW)) {
296 *wlen = sz;
297 return -ENODATA;
298 }
299 if (*wlen < sz) {
300 *wlen = sz;
301 return -EOVERFLOW;
302 }
303 base = oi->hwbase;
304 break;
305 case OTP_SW_RGN:
306 sz = ((uint) oi->swlim - oi->swbase);
307 if (!(oi->status & OTPS_GUP_SW)) {
308 *wlen = sz;
309 return -ENODATA;
310 }
311 if (*wlen < sz) {
312 *wlen = sz;
313 return -EOVERFLOW;
314 }
315 base = oi->swbase;
316 break;
317 case OTP_CI_RGN:
318 sz = OTPGU_CI_SZ;
319 if (!(oi->status & OTPS_GUP_CI)) {
320 *wlen = sz;
321 return -ENODATA;
322 }
323 if (*wlen < sz) {
324 *wlen = sz;
325 return -EOVERFLOW;
326 }
327 base = oi->otpgu_base + OTPGU_CI_OFF;
328 break;
329 case OTP_FUSE_RGN:
330 sz = (uint) oi->flim - oi->fbase;
331 if (!(oi->status & OTPS_GUP_FUSE)) {
332 *wlen = sz;
333 return -ENODATA;
334 }
335 if (*wlen < sz) {
336 *wlen = sz;
337 return -EOVERFLOW;
338 }
339 base = oi->fbase;
340 break;
341 case OTP_ALL_RGN:
342 sz = ((uint) oi->flim - oi->hwbase);
343 if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
344 *wlen = sz;
345 return -ENODATA;
346 }
347 if (*wlen < sz) {
348 *wlen = sz;
349 return -EOVERFLOW;
350 }
351 base = oi->hwbase;
352 break;
353 default:
354 return -EINVAL;
355 }
356
357 /* Read the data */
358 for (i = 0; i < sz; i++)
359 data[i] = ipxotp_otpr(oi, base + i);
360
361 *wlen = sz;
362 return 0;
363}
364
365static const struct otp_fn_s ipxotp_fn = {
366 (int (*)(struct si_pub *, struct otpinfo *)) ipxotp_init,
367 (int (*)(struct otpinfo *, int, u16 *, uint *)) ipxotp_read_region,
368};
369
370static int otp_init(struct si_pub *sih, struct otpinfo *oi)
371{
372 int ret;
373
374 memset(oi, 0, sizeof(struct otpinfo));
375
376 oi->core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
377
378 if (OTPTYPE_IPX(ai_get_ccrev(sih)))
379 oi->fn = &ipxotp_fn;
380
381 if (oi->fn == NULL)
382 return -EBADE;
383
384 oi->sih = sih;
385
386 ret = (oi->fn->init)(sih, oi);
387
388 return ret;
389}
390
391int
392otp_read_region(struct si_pub *sih, int region, u16 *data, uint *wlen) {
393 struct otpinfo otpinfo;
394 struct otpinfo *oi = &otpinfo;
395 int err = 0;
396
397 if (ai_is_otp_disabled(sih)) {
398 err = -EPERM;
399 goto out;
400 }
401
402 err = otp_init(sih, oi);
403 if (err)
404 goto out;
405
406 err = ((oi)->fn->read_region)(oi, region, data, wlen);
407
408 out:
409 return err;
410}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/otp.h b/drivers/net/wireless/brcm80211/brcmsmac/otp.h
deleted file mode 100644
index 6b6d31cf9569..000000000000
--- a/drivers/net/wireless/brcm80211/brcmsmac/otp.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_OTP_H_
18#define _BRCM_OTP_H_
19
20#include "types.h"
21
22/* OTP regions */
23#define OTP_HW_RGN 1
24#define OTP_SW_RGN 2
25#define OTP_CI_RGN 4
26#define OTP_FUSE_RGN 8
27/* From h/w region to end of OTP including checksum */
28#define OTP_ALL_RGN 0xf
29
30/* OTP Size */
31#define OTP_SZ_MAX (6144/8) /* maximum bytes in one CIS */
32
33extern int otp_read_region(struct si_pub *sih, int region, u16 *data,
34 uint *wlen);
35
36#endif /* _BRCM_OTP_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index 0fce56235f38..abfd78822fb8 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -4817,28 +4817,23 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
4817 s8 txpwr = 0; 4817 s8 txpwr = 0;
4818 int i; 4818 int i;
4819 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; 4819 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4820 struct phy_shim_info *shim = pi->sh->physhim; 4820 struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
4821 4821
4822 if (CHSPEC_IS2G(pi->radio_chanspec)) { 4822 if (CHSPEC_IS2G(pi->radio_chanspec)) {
4823 u16 cckpo = 0; 4823 u16 cckpo = 0;
4824 u32 offset_ofdm, offset_mcs; 4824 u32 offset_ofdm, offset_mcs;
4825 4825
4826 pi_lcn->lcnphy_tr_isolation_mid = 4826 pi_lcn->lcnphy_tr_isolation_mid = sprom->fem.ghz2.tr_iso;
4827 (u8)wlapi_getintvar(shim, BRCMS_SROM_TRISO2G);
4828 4827
4829 pi_lcn->lcnphy_rx_power_offset = 4828 pi_lcn->lcnphy_rx_power_offset = sprom->rxpo2g;
4830 (u8)wlapi_getintvar(shim, BRCMS_SROM_RXPO2G);
4831 4829
4832 pi->txpa_2g[0] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B0); 4830 pi->txpa_2g[0] = sprom->pa0b0;
4833 pi->txpa_2g[1] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B1); 4831 pi->txpa_2g[1] = sprom->pa0b1;
4834 pi->txpa_2g[2] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B2); 4832 pi->txpa_2g[2] = sprom->pa0b2;
4835 4833
4836 pi_lcn->lcnphy_rssi_vf = 4834 pi_lcn->lcnphy_rssi_vf = sprom->rssismf2g;
4837 (u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISMF2G); 4835 pi_lcn->lcnphy_rssi_vc = sprom->rssismc2g;
4838 pi_lcn->lcnphy_rssi_vc = 4836 pi_lcn->lcnphy_rssi_gs = sprom->rssisav2g;
4839 (u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISMC2G);
4840 pi_lcn->lcnphy_rssi_gs =
4841 (u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISAV2G);
4842 4837
4843 pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf; 4838 pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf;
4844 pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc; 4839 pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc;
@@ -4848,7 +4843,7 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
4848 pi_lcn->lcnphy_rssi_vc_hightemp = pi_lcn->lcnphy_rssi_vc; 4843 pi_lcn->lcnphy_rssi_vc_hightemp = pi_lcn->lcnphy_rssi_vc;
4849 pi_lcn->lcnphy_rssi_gs_hightemp = pi_lcn->lcnphy_rssi_gs; 4844 pi_lcn->lcnphy_rssi_gs_hightemp = pi_lcn->lcnphy_rssi_gs;
4850 4845
4851 txpwr = (s8)wlapi_getintvar(shim, BRCMS_SROM_MAXP2GA0); 4846 txpwr = sprom->core_pwr_info[0].maxpwr_2g;
4852 pi->tx_srom_max_2g = txpwr; 4847 pi->tx_srom_max_2g = txpwr;
4853 4848
4854 for (i = 0; i < PWRTBL_NUM_COEFF; i++) { 4849 for (i = 0; i < PWRTBL_NUM_COEFF; i++) {
@@ -4856,8 +4851,8 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
4856 pi->txpa_2g_high_temp[i] = pi->txpa_2g[i]; 4851 pi->txpa_2g_high_temp[i] = pi->txpa_2g[i];
4857 } 4852 }
4858 4853
4859 cckpo = (u16)wlapi_getintvar(shim, BRCMS_SROM_CCK2GPO); 4854 cckpo = sprom->cck2gpo;
4860 offset_ofdm = (u32)wlapi_getintvar(shim, BRCMS_SROM_OFDM2GPO); 4855 offset_ofdm = sprom->ofdm2gpo;
4861 if (cckpo) { 4856 if (cckpo) {
4862 uint max_pwr_chan = txpwr; 4857 uint max_pwr_chan = txpwr;
4863 4858
@@ -4876,7 +4871,7 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
4876 } else { 4871 } else {
4877 u8 opo = 0; 4872 u8 opo = 0;
4878 4873
4879 opo = (u8)wlapi_getintvar(shim, BRCMS_SROM_OPO); 4874 opo = sprom->opo;
4880 4875
4881 for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) 4876 for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++)
4882 pi->tx_srom_max_rate_2g[i] = txpwr; 4877 pi->tx_srom_max_rate_2g[i] = txpwr;
@@ -4886,12 +4881,8 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
4886 ((offset_ofdm & 0xf) * 2); 4881 ((offset_ofdm & 0xf) * 2);
4887 offset_ofdm >>= 4; 4882 offset_ofdm >>= 4;
4888 } 4883 }
4889 offset_mcs = 4884 offset_mcs = sprom->mcs2gpo[1] << 16;
4890 wlapi_getintvar(shim, 4885 offset_mcs |= sprom->mcs2gpo[0];
4891 BRCMS_SROM_MCS2GPO1) << 16;
4892 offset_mcs |=
4893 (u16) wlapi_getintvar(shim,
4894 BRCMS_SROM_MCS2GPO0);
4895 pi_lcn->lcnphy_mcs20_po = offset_mcs; 4886 pi_lcn->lcnphy_mcs20_po = offset_mcs;
4896 for (i = TXP_FIRST_SISO_MCS_20; 4887 for (i = TXP_FIRST_SISO_MCS_20;
4897 i <= TXP_LAST_SISO_MCS_20; i++) { 4888 i <= TXP_LAST_SISO_MCS_20; i++) {
@@ -4901,25 +4892,17 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
4901 } 4892 }
4902 } 4893 }
4903 4894
4904 pi_lcn->lcnphy_rawtempsense = 4895 pi_lcn->lcnphy_rawtempsense = sprom->rawtempsense;
4905 (u16)wlapi_getintvar(shim, BRCMS_SROM_RAWTEMPSENSE); 4896 pi_lcn->lcnphy_measPower = sprom->measpower;
4906 pi_lcn->lcnphy_measPower = 4897 pi_lcn->lcnphy_tempsense_slope = sprom->tempsense_slope;
4907 (u8)wlapi_getintvar(shim, BRCMS_SROM_MEASPOWER); 4898 pi_lcn->lcnphy_hw_iqcal_en = sprom->hw_iqcal_en;
4908 pi_lcn->lcnphy_tempsense_slope = 4899 pi_lcn->lcnphy_iqcal_swp_dis = sprom->iqcal_swp_dis;
4909 (u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPSENSE_SLOPE); 4900 pi_lcn->lcnphy_tempcorrx = sprom->tempcorrx;
4910 pi_lcn->lcnphy_hw_iqcal_en = 4901 pi_lcn->lcnphy_tempsense_option = sprom->tempsense_option;
4911 (bool)wlapi_getintvar(shim, BRCMS_SROM_HW_IQCAL_EN); 4902 pi_lcn->lcnphy_freqoffset_corr = sprom->freqoffset_corr;
4912 pi_lcn->lcnphy_iqcal_swp_dis = 4903 if (sprom->ant_available_bg > 1)
4913 (bool)wlapi_getintvar(shim, BRCMS_SROM_IQCAL_SWP_DIS);
4914 pi_lcn->lcnphy_tempcorrx =
4915 (u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPCORRX);
4916 pi_lcn->lcnphy_tempsense_option =
4917 (u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPSENSE_OPTION);
4918 pi_lcn->lcnphy_freqoffset_corr =
4919 (u8)wlapi_getintvar(shim, BRCMS_SROM_FREQOFFSET_CORR);
4920 if ((u8)wlapi_getintvar(shim, BRCMS_SROM_AA2G) > 1)
4921 wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi, 4904 wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi,
4922 (u8) wlapi_getintvar(shim, BRCMS_SROM_AA2G)); 4905 sprom->ant_available_bg);
4923 } 4906 }
4924 pi_lcn->lcnphy_cck_dig_filt_type = -1; 4907 pi_lcn->lcnphy_cck_dig_filt_type = -1;
4925 4908
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
index 812b6e38526e..13b261517cce 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+++ b/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)
14386{ 14386{
14387 u16 bw40po, cddpo, stbcpo, bwduppo; 14387 u16 bw40po, cddpo, stbcpo, bwduppo;
14388 uint band_num; 14388 uint band_num;
14389 struct phy_shim_info *shim = pi->sh->physhim; 14389 struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
14390 14390
14391 if (pi->sh->sromrev >= 9) 14391 if (pi->sh->sromrev >= 9)
14392 return; 14392 return;
14393 14393
14394 bw40po = (u16) wlapi_getintvar(shim, BRCMS_SROM_BW40PO); 14394 bw40po = sprom->bw40po;
14395 pi->bw402gpo = bw40po & 0xf; 14395 pi->bw402gpo = bw40po & 0xf;
14396 pi->bw405gpo = (bw40po & 0xf0) >> 4; 14396 pi->bw405gpo = (bw40po & 0xf0) >> 4;
14397 pi->bw405glpo = (bw40po & 0xf00) >> 8; 14397 pi->bw405glpo = (bw40po & 0xf00) >> 8;
14398 pi->bw405ghpo = (bw40po & 0xf000) >> 12; 14398 pi->bw405ghpo = (bw40po & 0xf000) >> 12;
14399 14399
14400 cddpo = (u16) wlapi_getintvar(shim, BRCMS_SROM_CDDPO); 14400 cddpo = sprom->cddpo;
14401 pi->cdd2gpo = cddpo & 0xf; 14401 pi->cdd2gpo = cddpo & 0xf;
14402 pi->cdd5gpo = (cddpo & 0xf0) >> 4; 14402 pi->cdd5gpo = (cddpo & 0xf0) >> 4;
14403 pi->cdd5glpo = (cddpo & 0xf00) >> 8; 14403 pi->cdd5glpo = (cddpo & 0xf00) >> 8;
14404 pi->cdd5ghpo = (cddpo & 0xf000) >> 12; 14404 pi->cdd5ghpo = (cddpo & 0xf000) >> 12;
14405 14405
14406 stbcpo = (u16) wlapi_getintvar(shim, BRCMS_SROM_STBCPO); 14406 stbcpo = sprom->stbcpo;
14407 pi->stbc2gpo = stbcpo & 0xf; 14407 pi->stbc2gpo = stbcpo & 0xf;
14408 pi->stbc5gpo = (stbcpo & 0xf0) >> 4; 14408 pi->stbc5gpo = (stbcpo & 0xf0) >> 4;
14409 pi->stbc5glpo = (stbcpo & 0xf00) >> 8; 14409 pi->stbc5glpo = (stbcpo & 0xf00) >> 8;
14410 pi->stbc5ghpo = (stbcpo & 0xf000) >> 12; 14410 pi->stbc5ghpo = (stbcpo & 0xf000) >> 12;
14411 14411
14412 bwduppo = (u16) wlapi_getintvar(shim, BRCMS_SROM_BWDUPPO); 14412 bwduppo = sprom->bwduppo;
14413 pi->bwdup2gpo = bwduppo & 0xf; 14413 pi->bwdup2gpo = bwduppo & 0xf;
14414 pi->bwdup5gpo = (bwduppo & 0xf0) >> 4; 14414 pi->bwdup5gpo = (bwduppo & 0xf0) >> 4;
14415 pi->bwdup5glpo = (bwduppo & 0xf00) >> 8; 14415 pi->bwdup5glpo = (bwduppo & 0xf00) >> 8;
@@ -14419,242 +14419,137 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi)
14419 band_num++) { 14419 band_num++) {
14420 switch (band_num) { 14420 switch (band_num) {
14421 case 0: 14421 case 0:
14422
14423 pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g = 14422 pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g =
14424 (s8) wlapi_getintvar(shim, 14423 sprom->core_pwr_info[0].maxpwr_2g;
14425 BRCMS_SROM_MAXP2GA0);
14426 pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g = 14424 pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g =
14427 (s8) wlapi_getintvar(shim, 14425 sprom->core_pwr_info[1].maxpwr_2g;
14428 BRCMS_SROM_MAXP2GA1);
14429 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 = 14426 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 =
14430 (s16) wlapi_getintvar(shim, 14427 sprom->core_pwr_info[0].pa_2g[0];
14431 BRCMS_SROM_PA2GW0A0);
14432 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 = 14428 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 =
14433 (s16) wlapi_getintvar(shim, 14429 sprom->core_pwr_info[1].pa_2g[0];
14434 BRCMS_SROM_PA2GW0A1);
14435 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 = 14430 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 =
14436 (s16) wlapi_getintvar(shim, 14431 sprom->core_pwr_info[0].pa_2g[1];
14437 BRCMS_SROM_PA2GW1A0);
14438 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 = 14432 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 =
14439 (s16) wlapi_getintvar(shim, 14433 sprom->core_pwr_info[1].pa_2g[1];
14440 BRCMS_SROM_PA2GW1A1);
14441 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 = 14434 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 =
14442 (s16) wlapi_getintvar(shim, 14435 sprom->core_pwr_info[0].pa_2g[2];
14443 BRCMS_SROM_PA2GW2A0);
14444 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 = 14436 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 =
14445 (s16) wlapi_getintvar(shim, 14437 sprom->core_pwr_info[1].pa_2g[2];
14446 BRCMS_SROM_PA2GW2A1);
14447 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g = 14438 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g =
14448 (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT2GA0); 14439 sprom->core_pwr_info[0].itssi_2g;
14449 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g = 14440 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g =
14450 (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT2GA1); 14441 sprom->core_pwr_info[1].itssi_2g;
14451 14442
14452 pi->cck2gpo = (u16) wlapi_getintvar(shim, 14443 pi->cck2gpo = sprom->cck2gpo;
14453 BRCMS_SROM_CCK2GPO); 14444
14454 14445 pi->ofdm2gpo = sprom->ofdm2gpo;
14455 pi->ofdm2gpo = 14446
14456 (u32) wlapi_getintvar(shim, 14447 pi->mcs2gpo[0] = sprom->mcs2gpo[0];
14457 BRCMS_SROM_OFDM2GPO); 14448 pi->mcs2gpo[1] = sprom->mcs2gpo[1];
14458 14449 pi->mcs2gpo[2] = sprom->mcs2gpo[2];
14459 pi->mcs2gpo[0] = 14450 pi->mcs2gpo[3] = sprom->mcs2gpo[3];
14460 (u16) wlapi_getintvar(shim, 14451 pi->mcs2gpo[4] = sprom->mcs2gpo[4];
14461 BRCMS_SROM_MCS2GPO0); 14452 pi->mcs2gpo[5] = sprom->mcs2gpo[5];
14462 pi->mcs2gpo[1] = 14453 pi->mcs2gpo[6] = sprom->mcs2gpo[6];
14463 (u16) wlapi_getintvar(shim, 14454 pi->mcs2gpo[7] = sprom->mcs2gpo[7];
14464 BRCMS_SROM_MCS2GPO1);
14465 pi->mcs2gpo[2] =
14466 (u16) wlapi_getintvar(shim,
14467 BRCMS_SROM_MCS2GPO2);
14468 pi->mcs2gpo[3] =
14469 (u16) wlapi_getintvar(shim,
14470 BRCMS_SROM_MCS2GPO3);
14471 pi->mcs2gpo[4] =
14472 (u16) wlapi_getintvar(shim,
14473 BRCMS_SROM_MCS2GPO4);
14474 pi->mcs2gpo[5] =
14475 (u16) wlapi_getintvar(shim,
14476 BRCMS_SROM_MCS2GPO5);
14477 pi->mcs2gpo[6] =
14478 (u16) wlapi_getintvar(shim,
14479 BRCMS_SROM_MCS2GPO6);
14480 pi->mcs2gpo[7] =
14481 (u16) wlapi_getintvar(shim,
14482 BRCMS_SROM_MCS2GPO7);
14483 break; 14455 break;
14484 case 1: 14456 case 1:
14485 14457
14486 pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm = 14458 pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm =
14487 (s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP5GA0); 14459 sprom->core_pwr_info[0].maxpwr_5g;
14488 pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm = 14460 pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm =
14489 (s8) wlapi_getintvar(shim, 14461 sprom->core_pwr_info[1].maxpwr_5g;
14490 BRCMS_SROM_MAXP5GA1);
14491 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 = 14462 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 =
14492 (s16) wlapi_getintvar(shim, 14463 sprom->core_pwr_info[0].pa_5g[0];
14493 BRCMS_SROM_PA5GW0A0);
14494 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 = 14464 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 =
14495 (s16) wlapi_getintvar(shim, 14465 sprom->core_pwr_info[1].pa_5g[0];
14496 BRCMS_SROM_PA5GW0A1);
14497 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 = 14466 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 =
14498 (s16) wlapi_getintvar(shim, 14467 sprom->core_pwr_info[0].pa_5g[1];
14499 BRCMS_SROM_PA5GW1A0);
14500 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 = 14468 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 =
14501 (s16) wlapi_getintvar(shim, 14469 sprom->core_pwr_info[1].pa_5g[1];
14502 BRCMS_SROM_PA5GW1A1);
14503 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 = 14470 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 =
14504 (s16) wlapi_getintvar(shim, 14471 sprom->core_pwr_info[0].pa_5g[2];
14505 BRCMS_SROM_PA5GW2A0);
14506 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 = 14472 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 =
14507 (s16) wlapi_getintvar(shim, 14473 sprom->core_pwr_info[1].pa_5g[2];
14508 BRCMS_SROM_PA5GW2A1);
14509 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm = 14474 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm =
14510 (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT5GA0); 14475 sprom->core_pwr_info[0].itssi_5g;
14511 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm = 14476 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm =
14512 (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT5GA1); 14477 sprom->core_pwr_info[1].itssi_5g;
14513 14478
14514 pi->ofdm5gpo = 14479 pi->ofdm5gpo = sprom->ofdm5gpo;
14515 (u32) wlapi_getintvar(shim, 14480
14516 BRCMS_SROM_OFDM5GPO); 14481 pi->mcs5gpo[0] = sprom->mcs5gpo[0];
14517 14482 pi->mcs5gpo[1] = sprom->mcs5gpo[1];
14518 pi->mcs5gpo[0] = 14483 pi->mcs5gpo[2] = sprom->mcs5gpo[2];
14519 (u16) wlapi_getintvar(shim, 14484 pi->mcs5gpo[3] = sprom->mcs5gpo[3];
14520 BRCMS_SROM_MCS5GPO0); 14485 pi->mcs5gpo[4] = sprom->mcs5gpo[4];
14521 pi->mcs5gpo[1] = 14486 pi->mcs5gpo[5] = sprom->mcs5gpo[5];
14522 (u16) wlapi_getintvar(shim, 14487 pi->mcs5gpo[6] = sprom->mcs5gpo[6];
14523 BRCMS_SROM_MCS5GPO1); 14488 pi->mcs5gpo[7] = sprom->mcs5gpo[7];
14524 pi->mcs5gpo[2] =
14525 (u16) wlapi_getintvar(shim,
14526 BRCMS_SROM_MCS5GPO2);
14527 pi->mcs5gpo[3] =
14528 (u16) wlapi_getintvar(shim,
14529 BRCMS_SROM_MCS5GPO3);
14530 pi->mcs5gpo[4] =
14531 (u16) wlapi_getintvar(shim,
14532 BRCMS_SROM_MCS5GPO4);
14533 pi->mcs5gpo[5] =
14534 (u16) wlapi_getintvar(shim,
14535 BRCMS_SROM_MCS5GPO5);
14536 pi->mcs5gpo[6] =
14537 (u16) wlapi_getintvar(shim,
14538 BRCMS_SROM_MCS5GPO6);
14539 pi->mcs5gpo[7] =
14540 (u16) wlapi_getintvar(shim,
14541 BRCMS_SROM_MCS5GPO7);
14542 break; 14489 break;
14543 case 2: 14490 case 2:
14544 14491
14545 pi->nphy_pwrctrl_info[0].max_pwr_5gl = 14492 pi->nphy_pwrctrl_info[0].max_pwr_5gl =
14546 (s8) wlapi_getintvar(shim, 14493 sprom->core_pwr_info[0].maxpwr_5gl;
14547 BRCMS_SROM_MAXP5GLA0);
14548 pi->nphy_pwrctrl_info[1].max_pwr_5gl = 14494 pi->nphy_pwrctrl_info[1].max_pwr_5gl =
14549 (s8) wlapi_getintvar(shim, 14495 sprom->core_pwr_info[1].maxpwr_5gl;
14550 BRCMS_SROM_MAXP5GLA1);
14551 pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 = 14496 pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 =
14552 (s16) wlapi_getintvar(shim, 14497 sprom->core_pwr_info[0].pa_5gl[0];
14553 BRCMS_SROM_PA5GLW0A0);
14554 pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 = 14498 pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 =
14555 (s16) wlapi_getintvar(shim, 14499 sprom->core_pwr_info[1].pa_5gl[0];
14556 BRCMS_SROM_PA5GLW0A1);
14557 pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 = 14500 pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 =
14558 (s16) wlapi_getintvar(shim, 14501 sprom->core_pwr_info[0].pa_5gl[1];
14559 BRCMS_SROM_PA5GLW1A0);
14560 pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 = 14502 pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 =
14561 (s16) wlapi_getintvar(shim, 14503 sprom->core_pwr_info[1].pa_5gl[1];
14562 BRCMS_SROM_PA5GLW1A1);
14563 pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 = 14504 pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 =
14564 (s16) wlapi_getintvar(shim, 14505 sprom->core_pwr_info[0].pa_5gl[2];
14565 BRCMS_SROM_PA5GLW2A0);
14566 pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 = 14506 pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 =
14567 (s16) wlapi_getintvar(shim, 14507 sprom->core_pwr_info[1].pa_5gl[2];
14568 BRCMS_SROM_PA5GLW2A1);
14569 pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0; 14508 pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0;
14570 pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0; 14509 pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0;
14571 14510
14572 pi->ofdm5glpo = 14511 pi->ofdm5glpo = sprom->ofdm5glpo;
14573 (u32) wlapi_getintvar(shim, 14512
14574 BRCMS_SROM_OFDM5GLPO); 14513 pi->mcs5glpo[0] = sprom->mcs5glpo[0];
14575 14514 pi->mcs5glpo[1] = sprom->mcs5glpo[1];
14576 pi->mcs5glpo[0] = 14515 pi->mcs5glpo[2] = sprom->mcs5glpo[2];
14577 (u16) wlapi_getintvar(shim, 14516 pi->mcs5glpo[3] = sprom->mcs5glpo[3];
14578 BRCMS_SROM_MCS5GLPO0); 14517 pi->mcs5glpo[4] = sprom->mcs5glpo[4];
14579 pi->mcs5glpo[1] = 14518 pi->mcs5glpo[5] = sprom->mcs5glpo[5];
14580 (u16) wlapi_getintvar(shim, 14519 pi->mcs5glpo[6] = sprom->mcs5glpo[6];
14581 BRCMS_SROM_MCS5GLPO1); 14520 pi->mcs5glpo[7] = sprom->mcs5glpo[7];
14582 pi->mcs5glpo[2] =
14583 (u16) wlapi_getintvar(shim,
14584 BRCMS_SROM_MCS5GLPO2);
14585 pi->mcs5glpo[3] =
14586 (u16) wlapi_getintvar(shim,
14587 BRCMS_SROM_MCS5GLPO3);
14588 pi->mcs5glpo[4] =
14589 (u16) wlapi_getintvar(shim,
14590 BRCMS_SROM_MCS5GLPO4);
14591 pi->mcs5glpo[5] =
14592 (u16) wlapi_getintvar(shim,
14593 BRCMS_SROM_MCS5GLPO5);
14594 pi->mcs5glpo[6] =
14595 (u16) wlapi_getintvar(shim,
14596 BRCMS_SROM_MCS5GLPO6);
14597 pi->mcs5glpo[7] =
14598 (u16) wlapi_getintvar(shim,
14599 BRCMS_SROM_MCS5GLPO7);
14600 break; 14521 break;
14601 case 3: 14522 case 3:
14602 14523
14603 pi->nphy_pwrctrl_info[0].max_pwr_5gh = 14524 pi->nphy_pwrctrl_info[0].max_pwr_5gh =
14604 (s8) wlapi_getintvar(shim, 14525 sprom->core_pwr_info[0].maxpwr_5gh;
14605 BRCMS_SROM_MAXP5GHA0);
14606 pi->nphy_pwrctrl_info[1].max_pwr_5gh = 14526 pi->nphy_pwrctrl_info[1].max_pwr_5gh =
14607 (s8) wlapi_getintvar(shim, 14527 sprom->core_pwr_info[1].maxpwr_5gh;
14608 BRCMS_SROM_MAXP5GHA1);
14609 pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 = 14528 pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 =
14610 (s16) wlapi_getintvar(shim, 14529 sprom->core_pwr_info[0].pa_5gh[0];
14611 BRCMS_SROM_PA5GHW0A0);
14612 pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 = 14530 pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 =
14613 (s16) wlapi_getintvar(shim, 14531 sprom->core_pwr_info[1].pa_5gh[0];
14614 BRCMS_SROM_PA5GHW0A1);
14615 pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 = 14532 pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 =
14616 (s16) wlapi_getintvar(shim, 14533 sprom->core_pwr_info[0].pa_5gh[1];
14617 BRCMS_SROM_PA5GHW1A0);
14618 pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 = 14534 pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 =
14619 (s16) wlapi_getintvar(shim, 14535 sprom->core_pwr_info[1].pa_5gh[1];
14620 BRCMS_SROM_PA5GHW1A1);
14621 pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 = 14536 pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 =
14622 (s16) wlapi_getintvar(shim, 14537 sprom->core_pwr_info[0].pa_5gh[2];
14623 BRCMS_SROM_PA5GHW2A0);
14624 pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 = 14538 pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 =
14625 (s16) wlapi_getintvar(shim, 14539 sprom->core_pwr_info[1].pa_5gh[2];
14626 BRCMS_SROM_PA5GHW2A1);
14627 pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0; 14540 pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0;
14628 pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0; 14541 pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0;
14629 14542
14630 pi->ofdm5ghpo = 14543 pi->ofdm5ghpo = sprom->ofdm5ghpo;
14631 (u32) wlapi_getintvar(shim, 14544
14632 BRCMS_SROM_OFDM5GHPO); 14545 pi->mcs5ghpo[0] = sprom->mcs5ghpo[0];
14633 14546 pi->mcs5ghpo[1] = sprom->mcs5ghpo[1];
14634 pi->mcs5ghpo[0] = 14547 pi->mcs5ghpo[2] = sprom->mcs5ghpo[2];
14635 (u16) wlapi_getintvar(shim, 14548 pi->mcs5ghpo[3] = sprom->mcs5ghpo[3];
14636 BRCMS_SROM_MCS5GHPO0); 14549 pi->mcs5ghpo[4] = sprom->mcs5ghpo[4];
14637 pi->mcs5ghpo[1] = 14550 pi->mcs5ghpo[5] = sprom->mcs5ghpo[5];
14638 (u16) wlapi_getintvar(shim, 14551 pi->mcs5ghpo[6] = sprom->mcs5ghpo[6];
14639 BRCMS_SROM_MCS5GHPO1); 14552 pi->mcs5ghpo[7] = sprom->mcs5ghpo[7];
14640 pi->mcs5ghpo[2] =
14641 (u16) wlapi_getintvar(shim,
14642 BRCMS_SROM_MCS5GHPO2);
14643 pi->mcs5ghpo[3] =
14644 (u16) wlapi_getintvar(shim,
14645 BRCMS_SROM_MCS5GHPO3);
14646 pi->mcs5ghpo[4] =
14647 (u16) wlapi_getintvar(shim,
14648 BRCMS_SROM_MCS5GHPO4);
14649 pi->mcs5ghpo[5] =
14650 (u16) wlapi_getintvar(shim,
14651 BRCMS_SROM_MCS5GHPO5);
14652 pi->mcs5ghpo[6] =
14653 (u16) wlapi_getintvar(shim,
14654 BRCMS_SROM_MCS5GHPO6);
14655 pi->mcs5ghpo[7] =
14656 (u16) wlapi_getintvar(shim,
14657 BRCMS_SROM_MCS5GHPO7);
14658 break; 14553 break;
14659 } 14554 }
14660 } 14555 }
@@ -14664,45 +14559,34 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi)
14664 14559
14665static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi) 14560static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi)
14666{ 14561{
14667 struct phy_shim_info *shim = pi->sh->physhim; 14562 struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
14668 14563
14669 pi->antswitch = (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWITCH); 14564 pi->antswitch = sprom->antswitch;
14670 pi->aa2g = (u8) wlapi_getintvar(shim, BRCMS_SROM_AA2G); 14565 pi->aa2g = sprom->ant_available_bg;
14671 pi->aa5g = (u8) wlapi_getintvar(shim, BRCMS_SROM_AA5G); 14566 pi->aa5g = sprom->ant_available_a;
14672 14567
14673 pi->srom_fem2g.tssipos = (u8) wlapi_getintvar(shim, 14568 pi->srom_fem2g.tssipos = sprom->fem.ghz2.tssipos;
14674 BRCMS_SROM_TSSIPOS2G); 14569 pi->srom_fem2g.extpagain = sprom->fem.ghz2.extpa_gain;
14675 pi->srom_fem2g.extpagain = (u8) wlapi_getintvar(shim, 14570 pi->srom_fem2g.pdetrange = sprom->fem.ghz2.pdet_range;
14676 BRCMS_SROM_EXTPAGAIN2G); 14571 pi->srom_fem2g.triso = sprom->fem.ghz2.tr_iso;
14677 pi->srom_fem2g.pdetrange = (u8) wlapi_getintvar(shim, 14572 pi->srom_fem2g.antswctrllut = sprom->fem.ghz2.antswlut;
14678 BRCMS_SROM_PDETRANGE2G); 14573
14679 pi->srom_fem2g.triso = (u8) wlapi_getintvar(shim, BRCMS_SROM_TRISO2G); 14574 pi->srom_fem5g.tssipos = sprom->fem.ghz5.tssipos;
14680 pi->srom_fem2g.antswctrllut = 14575 pi->srom_fem5g.extpagain = sprom->fem.ghz5.extpa_gain;
14681 (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL2G); 14576 pi->srom_fem5g.pdetrange = sprom->fem.ghz5.pdet_range;
14682 14577 pi->srom_fem5g.triso = sprom->fem.ghz5.tr_iso;
14683 pi->srom_fem5g.tssipos = (u8) wlapi_getintvar(shim, 14578 if (sprom->fem.ghz5.antswlut)
14684 BRCMS_SROM_TSSIPOS5G); 14579 pi->srom_fem5g.antswctrllut = sprom->fem.ghz5.antswlut;
14685 pi->srom_fem5g.extpagain = (u8) wlapi_getintvar(shim,
14686 BRCMS_SROM_EXTPAGAIN5G);
14687 pi->srom_fem5g.pdetrange = (u8) wlapi_getintvar(shim,
14688 BRCMS_SROM_PDETRANGE5G);
14689 pi->srom_fem5g.triso = (u8) wlapi_getintvar(shim, BRCMS_SROM_TRISO5G);
14690 if (wlapi_getvar(shim, BRCMS_SROM_ANTSWCTL5G))
14691 pi->srom_fem5g.antswctrllut =
14692 (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL5G);
14693 else 14580 else
14694 pi->srom_fem5g.antswctrllut = 14581 pi->srom_fem5g.antswctrllut = sprom->fem.ghz2.antswlut;
14695 (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL2G);
14696 14582
14697 wlc_phy_txpower_ipa_upd(pi); 14583 wlc_phy_txpower_ipa_upd(pi);
14698 14584
14699 pi->phy_txcore_disable_temp = 14585 pi->phy_txcore_disable_temp = sprom->tempthresh;
14700 (s16) wlapi_getintvar(shim, BRCMS_SROM_TEMPTHRESH);
14701 if (pi->phy_txcore_disable_temp == 0) 14586 if (pi->phy_txcore_disable_temp == 0)
14702 pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP; 14587 pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
14703 14588
14704 pi->phy_tempsense_offset = (s8) wlapi_getintvar(shim, 14589 pi->phy_tempsense_offset = sprom->tempoffset;
14705 BRCMS_SROM_TEMPOFFSET);
14706 if (pi->phy_tempsense_offset != 0) { 14590 if (pi->phy_tempsense_offset != 0) {
14707 if (pi->phy_tempsense_offset > 14591 if (pi->phy_tempsense_offset >
14708 (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET)) 14592 (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET))
@@ -14717,8 +14601,7 @@ static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi)
14717 pi->phy_txcore_enable_temp = 14601 pi->phy_txcore_enable_temp =
14718 pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP; 14602 pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP;
14719 14603
14720 pi->phycal_tempdelta = 14604 pi->phycal_tempdelta = sprom->phycal_tempdelta;
14721 (u8) wlapi_getintvar(shim, BRCMS_SROM_PHYCAL_TEMPDELTA);
14722 if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA) 14605 if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA)
14723 pi->phycal_tempdelta = 0; 14606 pi->phycal_tempdelta = 0;
14724 14607
@@ -21460,7 +21343,7 @@ void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init)
21460 write_phy_reg(pi, 0xc8, 0x0); 21343 write_phy_reg(pi, 0xc8, 0x0);
21461 write_phy_reg(pi, 0xc9, 0x0); 21344 write_phy_reg(pi, 0xc9, 0x0);
21462 21345
21463 ai_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY); 21346 bcma_chipco_gpio_control(&pi->d11core->bus->drv_cc, mask, mask);
21464 21347
21465 mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol)); 21348 mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
21466 mc &= ~MCTL_GPOUT_SEL_MASK; 21349 mc &= ~MCTL_GPOUT_SEL_MASK;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
index 5926854f62e2..a0de5db0cd64 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
@@ -214,12 +214,3 @@ wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
214{ 214{
215 brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel); 215 brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
216} 216}
217
218char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id)
219{
220 return getvar(physhim->wlc_hw->sih, id);
221}
222int wlapi_getintvar(struct phy_shim_info *physhim, enum brcms_srom_id id)
223{
224 return getintvar(physhim->wlc_hw->sih, id);
225}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
index 9168c459b185..2c5b66b75970 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
@@ -175,8 +175,5 @@ extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint,
175extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim, 175extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim,
176 u32 phy_mode); 176 u32 phy_mode);
177extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim); 177extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
178extern char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id);
179extern int wlapi_getintvar(struct phy_shim_info *physhim,
180 enum brcms_srom_id id);
181 178
182#endif /* _BRCM_PHY_SHIM_H_ */ 179#endif /* _BRCM_PHY_SHIM_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index f0038ad7d7bf..aa5d67f8d874 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -22,232 +22,6 @@
22#include "types.h" 22#include "types.h"
23#include "defs.h" 23#include "defs.h"
24 24
25enum brcms_srom_id {
26 BRCMS_SROM_NULL,
27 BRCMS_SROM_CONT,
28 BRCMS_SROM_AA2G,
29 BRCMS_SROM_AA5G,
30 BRCMS_SROM_AG0,
31 BRCMS_SROM_AG1,
32 BRCMS_SROM_AG2,
33 BRCMS_SROM_AG3,
34 BRCMS_SROM_ANTSWCTL2G,
35 BRCMS_SROM_ANTSWCTL5G,
36 BRCMS_SROM_ANTSWITCH,
37 BRCMS_SROM_BOARDFLAGS2,
38 BRCMS_SROM_BOARDFLAGS,
39 BRCMS_SROM_BOARDNUM,
40 BRCMS_SROM_BOARDREV,
41 BRCMS_SROM_BOARDTYPE,
42 BRCMS_SROM_BW40PO,
43 BRCMS_SROM_BWDUPPO,
44 BRCMS_SROM_BXA2G,
45 BRCMS_SROM_BXA5G,
46 BRCMS_SROM_CC,
47 BRCMS_SROM_CCK2GPO,
48 BRCMS_SROM_CCKBW202GPO,
49 BRCMS_SROM_CCKBW20UL2GPO,
50 BRCMS_SROM_CCODE,
51 BRCMS_SROM_CDDPO,
52 BRCMS_SROM_DEVID,
53 BRCMS_SROM_ET1MACADDR,
54 BRCMS_SROM_EXTPAGAIN2G,
55 BRCMS_SROM_EXTPAGAIN5G,
56 BRCMS_SROM_FREQOFFSET_CORR,
57 BRCMS_SROM_HW_IQCAL_EN,
58 BRCMS_SROM_IL0MACADDR,
59 BRCMS_SROM_IQCAL_SWP_DIS,
60 BRCMS_SROM_LEDBH0,
61 BRCMS_SROM_LEDBH1,
62 BRCMS_SROM_LEDBH2,
63 BRCMS_SROM_LEDBH3,
64 BRCMS_SROM_LEDDC,
65 BRCMS_SROM_LEGOFDM40DUPPO,
66 BRCMS_SROM_LEGOFDMBW202GPO,
67 BRCMS_SROM_LEGOFDMBW205GHPO,
68 BRCMS_SROM_LEGOFDMBW205GLPO,
69 BRCMS_SROM_LEGOFDMBW205GMPO,
70 BRCMS_SROM_LEGOFDMBW20UL2GPO,
71 BRCMS_SROM_LEGOFDMBW20UL5GHPO,
72 BRCMS_SROM_LEGOFDMBW20UL5GLPO,
73 BRCMS_SROM_LEGOFDMBW20UL5GMPO,
74 BRCMS_SROM_MACADDR,
75 BRCMS_SROM_MCS2GPO0,
76 BRCMS_SROM_MCS2GPO1,
77 BRCMS_SROM_MCS2GPO2,
78 BRCMS_SROM_MCS2GPO3,
79 BRCMS_SROM_MCS2GPO4,
80 BRCMS_SROM_MCS2GPO5,
81 BRCMS_SROM_MCS2GPO6,
82 BRCMS_SROM_MCS2GPO7,
83 BRCMS_SROM_MCS32PO,
84 BRCMS_SROM_MCS5GHPO0,
85 BRCMS_SROM_MCS5GHPO1,
86 BRCMS_SROM_MCS5GHPO2,
87 BRCMS_SROM_MCS5GHPO3,
88 BRCMS_SROM_MCS5GHPO4,
89 BRCMS_SROM_MCS5GHPO5,
90 BRCMS_SROM_MCS5GHPO6,
91 BRCMS_SROM_MCS5GHPO7,
92 BRCMS_SROM_MCS5GLPO0,
93 BRCMS_SROM_MCS5GLPO1,
94 BRCMS_SROM_MCS5GLPO2,
95 BRCMS_SROM_MCS5GLPO3,
96 BRCMS_SROM_MCS5GLPO4,
97 BRCMS_SROM_MCS5GLPO5,
98 BRCMS_SROM_MCS5GLPO6,
99 BRCMS_SROM_MCS5GLPO7,
100 BRCMS_SROM_MCS5GPO0,
101 BRCMS_SROM_MCS5GPO1,
102 BRCMS_SROM_MCS5GPO2,
103 BRCMS_SROM_MCS5GPO3,
104 BRCMS_SROM_MCS5GPO4,
105 BRCMS_SROM_MCS5GPO5,
106 BRCMS_SROM_MCS5GPO6,
107 BRCMS_SROM_MCS5GPO7,
108 BRCMS_SROM_MCSBW202GPO,
109 BRCMS_SROM_MCSBW205GHPO,
110 BRCMS_SROM_MCSBW205GLPO,
111 BRCMS_SROM_MCSBW205GMPO,
112 BRCMS_SROM_MCSBW20UL2GPO,
113 BRCMS_SROM_MCSBW20UL5GHPO,
114 BRCMS_SROM_MCSBW20UL5GLPO,
115 BRCMS_SROM_MCSBW20UL5GMPO,
116 BRCMS_SROM_MCSBW402GPO,
117 BRCMS_SROM_MCSBW405GHPO,
118 BRCMS_SROM_MCSBW405GLPO,
119 BRCMS_SROM_MCSBW405GMPO,
120 BRCMS_SROM_MEASPOWER,
121 BRCMS_SROM_OFDM2GPO,
122 BRCMS_SROM_OFDM5GHPO,
123 BRCMS_SROM_OFDM5GLPO,
124 BRCMS_SROM_OFDM5GPO,
125 BRCMS_SROM_OPO,
126 BRCMS_SROM_PA0B0,
127 BRCMS_SROM_PA0B1,
128 BRCMS_SROM_PA0B2,
129 BRCMS_SROM_PA0ITSSIT,
130 BRCMS_SROM_PA0MAXPWR,
131 BRCMS_SROM_PA1B0,
132 BRCMS_SROM_PA1B1,
133 BRCMS_SROM_PA1B2,
134 BRCMS_SROM_PA1HIB0,
135 BRCMS_SROM_PA1HIB1,
136 BRCMS_SROM_PA1HIB2,
137 BRCMS_SROM_PA1HIMAXPWR,
138 BRCMS_SROM_PA1ITSSIT,
139 BRCMS_SROM_PA1LOB0,
140 BRCMS_SROM_PA1LOB1,
141 BRCMS_SROM_PA1LOB2,
142 BRCMS_SROM_PA1LOMAXPWR,
143 BRCMS_SROM_PA1MAXPWR,
144 BRCMS_SROM_PDETRANGE2G,
145 BRCMS_SROM_PDETRANGE5G,
146 BRCMS_SROM_PHYCAL_TEMPDELTA,
147 BRCMS_SROM_RAWTEMPSENSE,
148 BRCMS_SROM_REGREV,
149 BRCMS_SROM_REV,
150 BRCMS_SROM_RSSISAV2G,
151 BRCMS_SROM_RSSISAV5G,
152 BRCMS_SROM_RSSISMC2G,
153 BRCMS_SROM_RSSISMC5G,
154 BRCMS_SROM_RSSISMF2G,
155 BRCMS_SROM_RSSISMF5G,
156 BRCMS_SROM_RXCHAIN,
157 BRCMS_SROM_RXPO2G,
158 BRCMS_SROM_RXPO5G,
159 BRCMS_SROM_STBCPO,
160 BRCMS_SROM_TEMPCORRX,
161 BRCMS_SROM_TEMPOFFSET,
162 BRCMS_SROM_TEMPSENSE_OPTION,
163 BRCMS_SROM_TEMPSENSE_SLOPE,
164 BRCMS_SROM_TEMPTHRESH,
165 BRCMS_SROM_TRI2G,
166 BRCMS_SROM_TRI5GH,
167 BRCMS_SROM_TRI5GL,
168 BRCMS_SROM_TRI5G,
169 BRCMS_SROM_TRISO2G,
170 BRCMS_SROM_TRISO5G,
171 BRCMS_SROM_TSSIPOS2G,
172 BRCMS_SROM_TSSIPOS5G,
173 BRCMS_SROM_TXCHAIN,
174 /*
175 * per-path identifiers (see srom.c)
176 */
177 BRCMS_SROM_ITT2GA0,
178 BRCMS_SROM_ITT2GA1,
179 BRCMS_SROM_ITT2GA2,
180 BRCMS_SROM_ITT2GA3,
181 BRCMS_SROM_ITT5GA0,
182 BRCMS_SROM_ITT5GA1,
183 BRCMS_SROM_ITT5GA2,
184 BRCMS_SROM_ITT5GA3,
185 BRCMS_SROM_MAXP2GA0,
186 BRCMS_SROM_MAXP2GA1,
187 BRCMS_SROM_MAXP2GA2,
188 BRCMS_SROM_MAXP2GA3,
189 BRCMS_SROM_MAXP5GA0,
190 BRCMS_SROM_MAXP5GA1,
191 BRCMS_SROM_MAXP5GA2,
192 BRCMS_SROM_MAXP5GA3,
193 BRCMS_SROM_MAXP5GHA0,
194 BRCMS_SROM_MAXP5GHA1,
195 BRCMS_SROM_MAXP5GHA2,
196 BRCMS_SROM_MAXP5GHA3,
197 BRCMS_SROM_MAXP5GLA0,
198 BRCMS_SROM_MAXP5GLA1,
199 BRCMS_SROM_MAXP5GLA2,
200 BRCMS_SROM_MAXP5GLA3,
201 BRCMS_SROM_PA2GW0A0,
202 BRCMS_SROM_PA2GW0A1,
203 BRCMS_SROM_PA2GW0A2,
204 BRCMS_SROM_PA2GW0A3,
205 BRCMS_SROM_PA2GW1A0,
206 BRCMS_SROM_PA2GW1A1,
207 BRCMS_SROM_PA2GW1A2,
208 BRCMS_SROM_PA2GW1A3,
209 BRCMS_SROM_PA2GW2A0,
210 BRCMS_SROM_PA2GW2A1,
211 BRCMS_SROM_PA2GW2A2,
212 BRCMS_SROM_PA2GW2A3,
213 BRCMS_SROM_PA5GHW0A0,
214 BRCMS_SROM_PA5GHW0A1,
215 BRCMS_SROM_PA5GHW0A2,
216 BRCMS_SROM_PA5GHW0A3,
217 BRCMS_SROM_PA5GHW1A0,
218 BRCMS_SROM_PA5GHW1A1,
219 BRCMS_SROM_PA5GHW1A2,
220 BRCMS_SROM_PA5GHW1A3,
221 BRCMS_SROM_PA5GHW2A0,
222 BRCMS_SROM_PA5GHW2A1,
223 BRCMS_SROM_PA5GHW2A2,
224 BRCMS_SROM_PA5GHW2A3,
225 BRCMS_SROM_PA5GLW0A0,
226 BRCMS_SROM_PA5GLW0A1,
227 BRCMS_SROM_PA5GLW0A2,
228 BRCMS_SROM_PA5GLW0A3,
229 BRCMS_SROM_PA5GLW1A0,
230 BRCMS_SROM_PA5GLW1A1,
231 BRCMS_SROM_PA5GLW1A2,
232 BRCMS_SROM_PA5GLW1A3,
233 BRCMS_SROM_PA5GLW2A0,
234 BRCMS_SROM_PA5GLW2A1,
235 BRCMS_SROM_PA5GLW2A2,
236 BRCMS_SROM_PA5GLW2A3,
237 BRCMS_SROM_PA5GW0A0,
238 BRCMS_SROM_PA5GW0A1,
239 BRCMS_SROM_PA5GW0A2,
240 BRCMS_SROM_PA5GW0A3,
241 BRCMS_SROM_PA5GW1A0,
242 BRCMS_SROM_PA5GW1A1,
243 BRCMS_SROM_PA5GW1A2,
244 BRCMS_SROM_PA5GW1A3,
245 BRCMS_SROM_PA5GW2A0,
246 BRCMS_SROM_PA5GW2A1,
247 BRCMS_SROM_PA5GW2A2,
248 BRCMS_SROM_PA5GW2A3,
249};
250
251#define BRCMS_NUMRATES 16 /* max # of rates in a rateset */ 25#define BRCMS_NUMRATES 16 /* max # of rates in a rateset */
252 26
253/* phy types */ 27/* phy types */
@@ -565,8 +339,6 @@ extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
565 struct ieee80211_sta *sta, u16 tid); 339 struct ieee80211_sta *sta, u16 tid);
566extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, 340extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
567 u8 ba_wsize, uint max_rx_ampdu_bytes); 341 u8 ba_wsize, uint max_rx_ampdu_bytes);
568extern char *getvar(struct si_pub *sih, enum brcms_srom_id id);
569extern int getintvar(struct si_pub *sih, enum brcms_srom_id id);
570extern int brcms_c_module_register(struct brcms_pub *pub, 342extern int brcms_c_module_register(struct brcms_pub *pub,
571 const char *name, struct brcms_info *hdl, 343 const char *name, struct brcms_info *hdl,
572 int (*down_fn)(void *handle)); 344 int (*down_fn)(void *handle));
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.c b/drivers/net/wireless/brcm80211/brcmsmac/srom.c
deleted file mode 100644
index b96f4b9d74bd..000000000000
--- a/drivers/net/wireless/brcm80211/brcmsmac/srom.c
+++ /dev/null
@@ -1,980 +0,0 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/kernel.h>
18#include <linux/string.h>
19#include <linux/io.h>
20#include <linux/etherdevice.h>
21#include <linux/crc8.h>
22#include <stdarg.h>
23
24#include <chipcommon.h>
25#include <brcmu_utils.h>
26#include "pub.h"
27#include "nicpci.h"
28#include "aiutils.h"
29#include "otp.h"
30#include "srom.h"
31#include "soc.h"
32
33/*
34 * SROM CRC8 polynomial value:
35 *
36 * x^8 + x^7 +x^6 + x^4 + x^2 + 1
37 */
38#define SROM_CRC8_POLY 0xAB
39
40/* Maximum srom: 6 Kilobits == 768 bytes */
41#define SROM_MAX 768
42
43/* PCI fields */
44#define PCI_F0DEVID 48
45
46#define SROM_WORDS 64
47
48#define SROM_SSID 2
49
50#define SROM_WL1LHMAXP 29
51
52#define SROM_WL1LPAB0 30
53#define SROM_WL1LPAB1 31
54#define SROM_WL1LPAB2 32
55
56#define SROM_WL1HPAB0 33
57#define SROM_WL1HPAB1 34
58#define SROM_WL1HPAB2 35
59
60#define SROM_MACHI_IL0 36
61#define SROM_MACMID_IL0 37
62#define SROM_MACLO_IL0 38
63#define SROM_MACHI_ET1 42
64#define SROM_MACMID_ET1 43
65#define SROM_MACLO_ET1 44
66
67#define SROM_BXARSSI2G 40
68#define SROM_BXARSSI5G 41
69
70#define SROM_TRI52G 42
71#define SROM_TRI5GHL 43
72
73#define SROM_RXPO52G 45
74
75#define SROM_AABREV 46
76/* Fields in AABREV */
77#define SROM_BR_MASK 0x00ff
78#define SROM_CC_MASK 0x0f00
79#define SROM_CC_SHIFT 8
80#define SROM_AA0_MASK 0x3000
81#define SROM_AA0_SHIFT 12
82#define SROM_AA1_MASK 0xc000
83#define SROM_AA1_SHIFT 14
84
85#define SROM_WL0PAB0 47
86#define SROM_WL0PAB1 48
87#define SROM_WL0PAB2 49
88
89#define SROM_LEDBH10 50
90#define SROM_LEDBH32 51
91
92#define SROM_WL10MAXP 52
93
94#define SROM_WL1PAB0 53
95#define SROM_WL1PAB1 54
96#define SROM_WL1PAB2 55
97
98#define SROM_ITT 56
99
100#define SROM_BFL 57
101#define SROM_BFL2 28
102
103#define SROM_AG10 58
104
105#define SROM_CCODE 59
106
107#define SROM_OPO 60
108
109#define SROM_CRCREV 63
110
111#define SROM4_WORDS 220
112
113#define SROM4_TXCHAIN_MASK 0x000f
114#define SROM4_RXCHAIN_MASK 0x00f0
115#define SROM4_SWITCH_MASK 0xff00
116
117/* Per-path fields */
118#define MAX_PATH_SROM 4
119
120#define SROM4_CRCREV 219
121
122/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6.
123 * This is acombined srom for both MIMO and SISO boards, usable in
124 * the .130 4Kilobit OTP with hardware redundancy.
125 */
126#define SROM8_BREV 65
127
128#define SROM8_BFL0 66
129#define SROM8_BFL1 67
130#define SROM8_BFL2 68
131#define SROM8_BFL3 69
132
133#define SROM8_MACHI 70
134#define SROM8_MACMID 71
135#define SROM8_MACLO 72
136
137#define SROM8_CCODE 73
138#define SROM8_REGREV 74
139
140#define SROM8_LEDBH10 75
141#define SROM8_LEDBH32 76
142
143#define SROM8_LEDDC 77
144
145#define SROM8_AA 78
146
147#define SROM8_AG10 79
148#define SROM8_AG32 80
149
150#define SROM8_TXRXC 81
151
152#define SROM8_BXARSSI2G 82
153#define SROM8_BXARSSI5G 83
154#define SROM8_TRI52G 84
155#define SROM8_TRI5GHL 85
156#define SROM8_RXPO52G 86
157
158#define SROM8_FEM2G 87
159#define SROM8_FEM5G 88
160#define SROM8_FEM_ANTSWLUT_MASK 0xf800
161#define SROM8_FEM_ANTSWLUT_SHIFT 11
162#define SROM8_FEM_TR_ISO_MASK 0x0700
163#define SROM8_FEM_TR_ISO_SHIFT 8
164#define SROM8_FEM_PDET_RANGE_MASK 0x00f8
165#define SROM8_FEM_PDET_RANGE_SHIFT 3
166#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006
167#define SROM8_FEM_EXTPA_GAIN_SHIFT 1
168#define SROM8_FEM_TSSIPOS_MASK 0x0001
169#define SROM8_FEM_TSSIPOS_SHIFT 0
170
171#define SROM8_THERMAL 89
172
173/* Temp sense related entries */
174#define SROM8_MPWR_RAWTS 90
175#define SROM8_TS_SLP_OPT_CORRX 91
176/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable,
177 * IQSWP: IQ CAL swap disable */
178#define SROM8_FOC_HWIQ_IQSWP 92
179
180/* Temperature delta for PHY calibration */
181#define SROM8_PHYCAL_TEMPDELTA 93
182
183/* Per-path offsets & fields */
184#define SROM8_PATH0 96
185#define SROM8_PATH1 112
186#define SROM8_PATH2 128
187#define SROM8_PATH3 144
188
189#define SROM8_2G_ITT_MAXP 0
190#define SROM8_2G_PA 1
191#define SROM8_5G_ITT_MAXP 4
192#define SROM8_5GLH_MAXP 5
193#define SROM8_5G_PA 6
194#define SROM8_5GL_PA 9
195#define SROM8_5GH_PA 12
196
197/* All the miriad power offsets */
198#define SROM8_2G_CCKPO 160
199
200#define SROM8_2G_OFDMPO 161
201#define SROM8_5G_OFDMPO 163
202#define SROM8_5GL_OFDMPO 165
203#define SROM8_5GH_OFDMPO 167
204
205#define SROM8_2G_MCSPO 169
206#define SROM8_5G_MCSPO 177
207#define SROM8_5GL_MCSPO 185
208#define SROM8_5GH_MCSPO 193
209
210#define SROM8_CDDPO 201
211#define SROM8_STBCPO 202
212#define SROM8_BW40PO 203
213#define SROM8_BWDUPPO 204
214
215/* SISO PA parameters are in the path0 spaces */
216#define SROM8_SISO 96
217
218/* Legacy names for SISO PA paramters */
219#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP)
220#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA)
221#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1)
222#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2)
223#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP)
224#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP)
225#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA)
226#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1)
227#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2)
228#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA)
229#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1)
230#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2)
231#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA)
232#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1)
233#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2)
234
235/* SROM REV 9 */
236#define SROM9_2GPO_CCKBW20 160
237#define SROM9_2GPO_CCKBW20UL 161
238#define SROM9_2GPO_LOFDMBW20 162
239#define SROM9_2GPO_LOFDMBW20UL 164
240
241#define SROM9_5GLPO_LOFDMBW20 166
242#define SROM9_5GLPO_LOFDMBW20UL 168
243#define SROM9_5GMPO_LOFDMBW20 170
244#define SROM9_5GMPO_LOFDMBW20UL 172
245#define SROM9_5GHPO_LOFDMBW20 174
246#define SROM9_5GHPO_LOFDMBW20UL 176
247
248#define SROM9_2GPO_MCSBW20 178
249#define SROM9_2GPO_MCSBW20UL 180
250#define SROM9_2GPO_MCSBW40 182
251
252#define SROM9_5GLPO_MCSBW20 184
253#define SROM9_5GLPO_MCSBW20UL 186
254#define SROM9_5GLPO_MCSBW40 188
255#define SROM9_5GMPO_MCSBW20 190
256#define SROM9_5GMPO_MCSBW20UL 192
257#define SROM9_5GMPO_MCSBW40 194
258#define SROM9_5GHPO_MCSBW20 196
259#define SROM9_5GHPO_MCSBW20UL 198
260#define SROM9_5GHPO_MCSBW40 200
261
262#define SROM9_PO_MCS32 202
263#define SROM9_PO_LOFDM40DUP 203
264
265/* SROM flags (see sromvar_t) */
266
267/* value continues as described by the next entry */
268#define SRFL_MORE 1
269#define SRFL_NOFFS 2 /* value bits can't be all one's */
270#define SRFL_PRHEX 4 /* value is in hexdecimal format */
271#define SRFL_PRSIGN 8 /* value is in signed decimal format */
272#define SRFL_CCODE 0x10 /* value is in country code format */
273#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */
274#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */
275/* do not generate a nvram param, entry is for mfgc */
276#define SRFL_NOVAR 0x80
277
278/* Max. nvram variable table size */
279#define MAXSZ_NVRAM_VARS 4096
280
281/*
282 * indicates type of value.
283 */
284enum brcms_srom_var_type {
285 BRCMS_SROM_STRING,
286 BRCMS_SROM_SNUMBER,
287 BRCMS_SROM_UNUMBER
288};
289
290/*
291 * storage type for srom variable.
292 *
293 * var_list: for linked list operations.
294 * varid: identifier of the variable.
295 * var_type: type of variable.
296 * buf: variable value when var_type == BRCMS_SROM_STRING.
297 * uval: unsigned variable value when var_type == BRCMS_SROM_UNUMBER.
298 * sval: signed variable value when var_type == BRCMS_SROM_SNUMBER.
299 */
300struct brcms_srom_list_head {
301 struct list_head var_list;
302 enum brcms_srom_id varid;
303 enum brcms_srom_var_type var_type;
304 union {
305 char buf[0];
306 u32 uval;
307 s32 sval;
308 };
309};
310
311struct brcms_sromvar {
312 enum brcms_srom_id varid;
313 u32 revmask;
314 u32 flags;
315 u16 off;
316 u16 mask;
317};
318
319struct brcms_varbuf {
320 char *base; /* pointer to buffer base */
321 char *buf; /* pointer to current position */
322 unsigned int size; /* current (residual) size in bytes */
323};
324
325/*
326 * Assumptions:
327 * - Ethernet address spans across 3 consecutive words
328 *
329 * Table rules:
330 * - Add multiple entries next to each other if a value spans across multiple
331 * words (even multiple fields in the same word) with each entry except the
332 * last having it's SRFL_MORE bit set.
333 * - Ethernet address entry does not follow above rule and must not have
334 * SRFL_MORE bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
335 * - The last entry's name field must be NULL to indicate the end of the table.
336 * Other entries must have non-NULL name.
337 */
338static const struct brcms_sromvar pci_sromvars[] = {
339 {BRCMS_SROM_DEVID, 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID,
340 0xffff},
341 {BRCMS_SROM_BOARDREV, 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
342 {BRCMS_SROM_BOARDFLAGS, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0,
343 0xffff},
344 {BRCMS_SROM_CONT, 0, 0, SROM8_BFL1, 0xffff},
345 {BRCMS_SROM_BOARDFLAGS2, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2,
346 0xffff},
347 {BRCMS_SROM_CONT, 0, 0, SROM8_BFL3, 0xffff},
348 {BRCMS_SROM_BOARDTYPE, 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
349 {BRCMS_SROM_BOARDNUM, 0xffffff00, 0, SROM8_MACLO, 0xffff},
350 {BRCMS_SROM_REGREV, 0xffffff00, 0, SROM8_REGREV, 0x00ff},
351 {BRCMS_SROM_LEDBH0, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
352 {BRCMS_SROM_LEDBH1, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
353 {BRCMS_SROM_LEDBH2, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
354 {BRCMS_SROM_LEDBH3, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
355 {BRCMS_SROM_PA0B0, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
356 {BRCMS_SROM_PA0B1, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
357 {BRCMS_SROM_PA0B2, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
358 {BRCMS_SROM_PA0ITSSIT, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
359 {BRCMS_SROM_PA0MAXPWR, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
360 {BRCMS_SROM_OPO, 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
361 {BRCMS_SROM_AA2G, 0xffffff00, 0, SROM8_AA, 0x00ff},
362 {BRCMS_SROM_AA5G, 0xffffff00, 0, SROM8_AA, 0xff00},
363 {BRCMS_SROM_AG0, 0xffffff00, 0, SROM8_AG10, 0x00ff},
364 {BRCMS_SROM_AG1, 0xffffff00, 0, SROM8_AG10, 0xff00},
365 {BRCMS_SROM_AG2, 0xffffff00, 0, SROM8_AG32, 0x00ff},
366 {BRCMS_SROM_AG3, 0xffffff00, 0, SROM8_AG32, 0xff00},
367 {BRCMS_SROM_PA1B0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
368 {BRCMS_SROM_PA1B1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
369 {BRCMS_SROM_PA1B2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
370 {BRCMS_SROM_PA1LOB0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
371 {BRCMS_SROM_PA1LOB1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
372 {BRCMS_SROM_PA1LOB2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
373 {BRCMS_SROM_PA1HIB0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
374 {BRCMS_SROM_PA1HIB1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
375 {BRCMS_SROM_PA1HIB2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
376 {BRCMS_SROM_PA1ITSSIT, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
377 {BRCMS_SROM_PA1MAXPWR, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
378 {BRCMS_SROM_PA1LOMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
379 {BRCMS_SROM_PA1HIMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
380 {BRCMS_SROM_BXA2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
381 {BRCMS_SROM_RSSISAV2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
382 {BRCMS_SROM_RSSISMC2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
383 {BRCMS_SROM_RSSISMF2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
384 {BRCMS_SROM_BXA5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
385 {BRCMS_SROM_RSSISAV5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
386 {BRCMS_SROM_RSSISMC5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
387 {BRCMS_SROM_RSSISMF5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
388 {BRCMS_SROM_TRI2G, 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
389 {BRCMS_SROM_TRI5G, 0xffffff00, 0, SROM8_TRI52G, 0xff00},
390 {BRCMS_SROM_TRI5GL, 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
391 {BRCMS_SROM_TRI5GH, 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
392 {BRCMS_SROM_RXPO2G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
393 {BRCMS_SROM_RXPO5G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
394 {BRCMS_SROM_TXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
395 SROM4_TXCHAIN_MASK},
396 {BRCMS_SROM_RXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
397 SROM4_RXCHAIN_MASK},
398 {BRCMS_SROM_ANTSWITCH, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
399 SROM4_SWITCH_MASK},
400 {BRCMS_SROM_TSSIPOS2G, 0xffffff00, 0, SROM8_FEM2G,
401 SROM8_FEM_TSSIPOS_MASK},
402 {BRCMS_SROM_EXTPAGAIN2G, 0xffffff00, 0, SROM8_FEM2G,
403 SROM8_FEM_EXTPA_GAIN_MASK},
404 {BRCMS_SROM_PDETRANGE2G, 0xffffff00, 0, SROM8_FEM2G,
405 SROM8_FEM_PDET_RANGE_MASK},
406 {BRCMS_SROM_TRISO2G, 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
407 {BRCMS_SROM_ANTSWCTL2G, 0xffffff00, 0, SROM8_FEM2G,
408 SROM8_FEM_ANTSWLUT_MASK},
409 {BRCMS_SROM_TSSIPOS5G, 0xffffff00, 0, SROM8_FEM5G,
410 SROM8_FEM_TSSIPOS_MASK},
411 {BRCMS_SROM_EXTPAGAIN5G, 0xffffff00, 0, SROM8_FEM5G,
412 SROM8_FEM_EXTPA_GAIN_MASK},
413 {BRCMS_SROM_PDETRANGE5G, 0xffffff00, 0, SROM8_FEM5G,
414 SROM8_FEM_PDET_RANGE_MASK},
415 {BRCMS_SROM_TRISO5G, 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
416 {BRCMS_SROM_ANTSWCTL5G, 0xffffff00, 0, SROM8_FEM5G,
417 SROM8_FEM_ANTSWLUT_MASK},
418 {BRCMS_SROM_TEMPTHRESH, 0xffffff00, 0, SROM8_THERMAL, 0xff00},
419 {BRCMS_SROM_TEMPOFFSET, 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
420
421 {BRCMS_SROM_CCODE, 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
422 {BRCMS_SROM_MACADDR, 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
423 {BRCMS_SROM_LEDDC, 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC,
424 0xffff},
425 {BRCMS_SROM_RAWTEMPSENSE, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS,
426 0x01ff},
427 {BRCMS_SROM_MEASPOWER, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS,
428 0xfe00},
429 {BRCMS_SROM_TEMPSENSE_SLOPE, 0xffffff00, SRFL_PRHEX,
430 SROM8_TS_SLP_OPT_CORRX, 0x00ff},
431 {BRCMS_SROM_TEMPCORRX, 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
432 0xfc00},
433 {BRCMS_SROM_TEMPSENSE_OPTION, 0xffffff00, SRFL_PRHEX,
434 SROM8_TS_SLP_OPT_CORRX, 0x0300},
435 {BRCMS_SROM_FREQOFFSET_CORR, 0xffffff00, SRFL_PRHEX,
436 SROM8_FOC_HWIQ_IQSWP, 0x000f},
437 {BRCMS_SROM_IQCAL_SWP_DIS, 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
438 0x0010},
439 {BRCMS_SROM_HW_IQCAL_EN, 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
440 0x0020},
441 {BRCMS_SROM_PHYCAL_TEMPDELTA, 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA,
442 0x00ff},
443
444 {BRCMS_SROM_CCK2GPO, 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
445 {BRCMS_SROM_OFDM2GPO, 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
446 {BRCMS_SROM_CONT, 0, 0, SROM8_2G_OFDMPO + 1, 0xffff},
447 {BRCMS_SROM_OFDM5GPO, 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
448 {BRCMS_SROM_CONT, 0, 0, SROM8_5G_OFDMPO + 1, 0xffff},
449 {BRCMS_SROM_OFDM5GLPO, 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
450 {BRCMS_SROM_CONT, 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff},
451 {BRCMS_SROM_OFDM5GHPO, 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
452 {BRCMS_SROM_CONT, 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff},
453 {BRCMS_SROM_MCS2GPO0, 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
454 {BRCMS_SROM_MCS2GPO1, 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff},
455 {BRCMS_SROM_MCS2GPO2, 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff},
456 {BRCMS_SROM_MCS2GPO3, 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff},
457 {BRCMS_SROM_MCS2GPO4, 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff},
458 {BRCMS_SROM_MCS2GPO5, 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff},
459 {BRCMS_SROM_MCS2GPO6, 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff},
460 {BRCMS_SROM_MCS2GPO7, 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff},
461 {BRCMS_SROM_MCS5GPO0, 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
462 {BRCMS_SROM_MCS5GPO1, 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff},
463 {BRCMS_SROM_MCS5GPO2, 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff},
464 {BRCMS_SROM_MCS5GPO3, 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff},
465 {BRCMS_SROM_MCS5GPO4, 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff},
466 {BRCMS_SROM_MCS5GPO5, 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff},
467 {BRCMS_SROM_MCS5GPO6, 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff},
468 {BRCMS_SROM_MCS5GPO7, 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff},
469 {BRCMS_SROM_MCS5GLPO0, 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
470 {BRCMS_SROM_MCS5GLPO1, 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff},
471 {BRCMS_SROM_MCS5GLPO2, 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff},
472 {BRCMS_SROM_MCS5GLPO3, 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff},
473 {BRCMS_SROM_MCS5GLPO4, 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff},
474 {BRCMS_SROM_MCS5GLPO5, 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff},
475 {BRCMS_SROM_MCS5GLPO6, 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff},
476 {BRCMS_SROM_MCS5GLPO7, 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff},
477 {BRCMS_SROM_MCS5GHPO0, 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
478 {BRCMS_SROM_MCS5GHPO1, 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff},
479 {BRCMS_SROM_MCS5GHPO2, 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff},
480 {BRCMS_SROM_MCS5GHPO3, 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff},
481 {BRCMS_SROM_MCS5GHPO4, 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff},
482 {BRCMS_SROM_MCS5GHPO5, 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff},
483 {BRCMS_SROM_MCS5GHPO6, 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff},
484 {BRCMS_SROM_MCS5GHPO7, 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff},
485 {BRCMS_SROM_CDDPO, 0x00000100, 0, SROM8_CDDPO, 0xffff},
486 {BRCMS_SROM_STBCPO, 0x00000100, 0, SROM8_STBCPO, 0xffff},
487 {BRCMS_SROM_BW40PO, 0x00000100, 0, SROM8_BW40PO, 0xffff},
488 {BRCMS_SROM_BWDUPPO, 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
489
490 /* power per rate from sromrev 9 */
491 {BRCMS_SROM_CCKBW202GPO, 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
492 {BRCMS_SROM_CCKBW20UL2GPO, 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
493 {BRCMS_SROM_LEGOFDMBW202GPO, 0xfffffe00, SRFL_MORE,
494 SROM9_2GPO_LOFDMBW20, 0xffff},
495 {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff},
496 {BRCMS_SROM_LEGOFDMBW20UL2GPO, 0xfffffe00, SRFL_MORE,
497 SROM9_2GPO_LOFDMBW20UL, 0xffff},
498 {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff},
499 {BRCMS_SROM_LEGOFDMBW205GLPO, 0xfffffe00, SRFL_MORE,
500 SROM9_5GLPO_LOFDMBW20, 0xffff},
501 {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff},
502 {BRCMS_SROM_LEGOFDMBW20UL5GLPO, 0xfffffe00, SRFL_MORE,
503 SROM9_5GLPO_LOFDMBW20UL, 0xffff},
504 {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff},
505 {BRCMS_SROM_LEGOFDMBW205GMPO, 0xfffffe00, SRFL_MORE,
506 SROM9_5GMPO_LOFDMBW20, 0xffff},
507 {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff},
508 {BRCMS_SROM_LEGOFDMBW20UL5GMPO, 0xfffffe00, SRFL_MORE,
509 SROM9_5GMPO_LOFDMBW20UL, 0xffff},
510 {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff},
511 {BRCMS_SROM_LEGOFDMBW205GHPO, 0xfffffe00, SRFL_MORE,
512 SROM9_5GHPO_LOFDMBW20, 0xffff},
513 {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff},
514 {BRCMS_SROM_LEGOFDMBW20UL5GHPO, 0xfffffe00, SRFL_MORE,
515 SROM9_5GHPO_LOFDMBW20UL, 0xffff},
516 {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff},
517 {BRCMS_SROM_MCSBW202GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20,
518 0xffff},
519 {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff},
520 {BRCMS_SROM_MCSBW20UL2GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL,
521 0xffff},
522 {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff},
523 {BRCMS_SROM_MCSBW402GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40,
524 0xffff},
525 {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff},
526 {BRCMS_SROM_MCSBW205GLPO, 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20,
527 0xffff},
528 {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff},
529 {BRCMS_SROM_MCSBW20UL5GLPO, 0xfffffe00, SRFL_MORE,
530 SROM9_5GLPO_MCSBW20UL, 0xffff},
531 {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff},
532 {BRCMS_SROM_MCSBW405GLPO, 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40,
533 0xffff},
534 {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff},
535 {BRCMS_SROM_MCSBW205GMPO, 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20,
536 0xffff},
537 {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff},
538 {BRCMS_SROM_MCSBW20UL5GMPO, 0xfffffe00, SRFL_MORE,
539 SROM9_5GMPO_MCSBW20UL, 0xffff},
540 {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff},
541 {BRCMS_SROM_MCSBW405GMPO, 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40,
542 0xffff},
543 {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff},
544 {BRCMS_SROM_MCSBW205GHPO, 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20,
545 0xffff},
546 {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff},
547 {BRCMS_SROM_MCSBW20UL5GHPO, 0xfffffe00, SRFL_MORE,
548 SROM9_5GHPO_MCSBW20UL, 0xffff},
549 {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff},
550 {BRCMS_SROM_MCSBW405GHPO, 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40,
551 0xffff},
552 {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff},
553 {BRCMS_SROM_MCS32PO, 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
554 {BRCMS_SROM_LEGOFDM40DUPPO, 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
555
556 {BRCMS_SROM_NULL, 0, 0, 0, 0}
557};
558
559static const struct brcms_sromvar perpath_pci_sromvars[] = {
560 {BRCMS_SROM_MAXP2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
561 {BRCMS_SROM_ITT2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
562 {BRCMS_SROM_ITT5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
563 {BRCMS_SROM_PA2GW0A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
564 {BRCMS_SROM_PA2GW1A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff},
565 {BRCMS_SROM_PA2GW2A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff},
566 {BRCMS_SROM_MAXP5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
567 {BRCMS_SROM_MAXP5GHA0, 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
568 {BRCMS_SROM_MAXP5GLA0, 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
569 {BRCMS_SROM_PA5GW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
570 {BRCMS_SROM_PA5GW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff},
571 {BRCMS_SROM_PA5GW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff},
572 {BRCMS_SROM_PA5GLW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
573 {BRCMS_SROM_PA5GLW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1,
574 0xffff},
575 {BRCMS_SROM_PA5GLW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2,
576 0xffff},
577 {BRCMS_SROM_PA5GHW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
578 {BRCMS_SROM_PA5GHW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1,
579 0xffff},
580 {BRCMS_SROM_PA5GHW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2,
581 0xffff},
582 {BRCMS_SROM_NULL, 0, 0, 0, 0}
583};
584
585/* crc table has the same contents for every device instance, so it can be
586 * shared between devices. */
587static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE];
588
589static uint mask_shift(u16 mask)
590{
591 uint i;
592 for (i = 0; i < (sizeof(mask) << 3); i++) {
593 if (mask & (1 << i))
594 return i;
595 }
596 return 0;
597}
598
599static uint mask_width(u16 mask)
600{
601 int i;
602 for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) {
603 if (mask & (1 << i))
604 return (uint) (i - mask_shift(mask) + 1);
605 }
606 return 0;
607}
608
609static inline void le16_to_cpu_buf(u16 *buf, uint nwords)
610{
611 while (nwords--)
612 *(buf + nwords) = le16_to_cpu(*(__le16 *)(buf + nwords));
613}
614
615static inline void cpu_to_le16_buf(u16 *buf, uint nwords)
616{
617 while (nwords--)
618 *(__le16 *)(buf + nwords) = cpu_to_le16(*(buf + nwords));
619}
620
621/*
622 * convert binary srom data into linked list of srom variable items.
623 */
624static int
625_initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
626{
627 struct brcms_srom_list_head *entry;
628 enum brcms_srom_id id;
629 u16 w;
630 u32 val = 0;
631 const struct brcms_sromvar *srv;
632 uint width;
633 uint flags;
634 u32 sr = (1 << sromrev);
635 uint p;
636 uint pb = SROM8_PATH0;
637 const uint psz = SROM8_PATH1 - SROM8_PATH0;
638
639 /* first store the srom revision */
640 entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL);
641 if (!entry)
642 return -ENOMEM;
643
644 entry->varid = BRCMS_SROM_REV;
645 entry->var_type = BRCMS_SROM_UNUMBER;
646 entry->uval = sromrev;
647 list_add(&entry->var_list, var_list);
648
649 for (srv = pci_sromvars; srv->varid != BRCMS_SROM_NULL; srv++) {
650 enum brcms_srom_var_type type;
651 u8 ea[ETH_ALEN];
652 u8 extra_space = 0;
653
654 if ((srv->revmask & sr) == 0)
655 continue;
656
657 flags = srv->flags;
658 id = srv->varid;
659
660 /* This entry is for mfgc only. Don't generate param for it, */
661 if (flags & SRFL_NOVAR)
662 continue;
663
664 if (flags & SRFL_ETHADDR) {
665 /*
666 * stored in string format XX:XX:XX:XX:XX:XX (17 chars)
667 */
668 ea[0] = (srom[srv->off] >> 8) & 0xff;
669 ea[1] = srom[srv->off] & 0xff;
670 ea[2] = (srom[srv->off + 1] >> 8) & 0xff;
671 ea[3] = srom[srv->off + 1] & 0xff;
672 ea[4] = (srom[srv->off + 2] >> 8) & 0xff;
673 ea[5] = srom[srv->off + 2] & 0xff;
674 /* 17 characters + string terminator - union size */
675 extra_space = 18 - sizeof(s32);
676 type = BRCMS_SROM_STRING;
677 } else {
678 w = srom[srv->off];
679 val = (w & srv->mask) >> mask_shift(srv->mask);
680 width = mask_width(srv->mask);
681
682 while (srv->flags & SRFL_MORE) {
683 srv++;
684 if (srv->off == 0)
685 continue;
686
687 w = srom[srv->off];
688 val +=
689 ((w & srv->mask) >> mask_shift(srv->
690 mask)) <<
691 width;
692 width += mask_width(srv->mask);
693 }
694
695 if ((flags & SRFL_NOFFS)
696 && ((int)val == (1 << width) - 1))
697 continue;
698
699 if (flags & SRFL_CCODE) {
700 type = BRCMS_SROM_STRING;
701 } else if (flags & SRFL_LEDDC) {
702 /* LED Powersave duty cycle has to be scaled:
703 *(oncount >> 24) (offcount >> 8)
704 */
705 u32 w32 = /* oncount */
706 (((val >> 8) & 0xff) << 24) |
707 /* offcount */
708 (((val & 0xff)) << 8);
709 type = BRCMS_SROM_UNUMBER;
710 val = w32;
711 } else if ((flags & SRFL_PRSIGN)
712 && (val & (1 << (width - 1)))) {
713 type = BRCMS_SROM_SNUMBER;
714 val |= ~0 << width;
715 } else
716 type = BRCMS_SROM_UNUMBER;
717 }
718
719 entry = kzalloc(sizeof(struct brcms_srom_list_head) +
720 extra_space, GFP_KERNEL);
721 if (!entry)
722 return -ENOMEM;
723 entry->varid = id;
724 entry->var_type = type;
725 if (flags & SRFL_ETHADDR) {
726 snprintf(entry->buf, 18, "%pM", ea);
727 } else if (flags & SRFL_CCODE) {
728 if (val == 0)
729 entry->buf[0] = '\0';
730 else
731 snprintf(entry->buf, 3, "%c%c",
732 (val >> 8), (val & 0xff));
733 } else {
734 entry->uval = val;
735 }
736
737 list_add(&entry->var_list, var_list);
738 }
739
740 for (p = 0; p < MAX_PATH_SROM; p++) {
741 for (srv = perpath_pci_sromvars;
742 srv->varid != BRCMS_SROM_NULL; srv++) {
743 if ((srv->revmask & sr) == 0)
744 continue;
745
746 if (srv->flags & SRFL_NOVAR)
747 continue;
748
749 w = srom[pb + srv->off];
750 val = (w & srv->mask) >> mask_shift(srv->mask);
751 width = mask_width(srv->mask);
752
753 /* Cheating: no per-path var is more than
754 * 1 word */
755 if ((srv->flags & SRFL_NOFFS)
756 && ((int)val == (1 << width) - 1))
757 continue;
758
759 entry =
760 kzalloc(sizeof(struct brcms_srom_list_head),
761 GFP_KERNEL);
762 if (!entry)
763 return -ENOMEM;
764 entry->varid = srv->varid+p;
765 entry->var_type = BRCMS_SROM_UNUMBER;
766 entry->uval = val;
767 list_add(&entry->var_list, var_list);
768 }
769 pb += psz;
770 }
771 return 0;
772}
773
774/*
775 * The crc check is done on a little-endian array, we need
776 * to switch the bytes around before checking crc (and
777 * then switch it back).
778 */
779static int do_crc_check(u16 *buf, unsigned nwords)
780{
781 u8 crc;
782
783 cpu_to_le16_buf(buf, nwords);
784 crc = crc8(brcms_srom_crc8_table, (void *)buf, nwords << 1, CRC8_INIT_VALUE);
785 le16_to_cpu_buf(buf, nwords);
786
787 return crc == CRC8_GOOD_VALUE(brcms_srom_crc8_table);
788}
789
790/*
791 * Read in and validate sprom.
792 * Return 0 on success, nonzero on error.
793 */
794static int
795sprom_read_pci(struct si_pub *sih, u16 *buf, uint nwords, bool check_crc)
796{
797 int err = 0;
798 uint i;
799 struct bcma_device *core;
800 uint sprom_offset;
801
802 /* determine core to read */
803 if (ai_get_ccrev(sih) < 32) {
804 core = ai_findcore(sih, BCMA_CORE_80211, 0);
805 sprom_offset = PCI_BAR0_SPROM_OFFSET;
806 } else {
807 core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
808 sprom_offset = CHIPCREGOFFS(sromotp);
809 }
810
811 /* read the sprom */
812 for (i = 0; i < nwords; i++)
813 buf[i] = bcma_read16(core, sprom_offset+i*2);
814
815 if (buf[0] == 0xffff)
816 /*
817 * The hardware thinks that an srom that starts with
818 * 0xffff is blank, regardless of the rest of the
819 * content, so declare it bad.
820 */
821 return -ENODATA;
822
823 if (check_crc && !do_crc_check(buf, nwords))
824 err = -EIO;
825
826 return err;
827}
828
829static int otp_read_pci(struct si_pub *sih, u16 *buf, uint nwords)
830{
831 u8 *otp;
832 uint sz = OTP_SZ_MAX / 2; /* size in words */
833 int err = 0;
834
835 otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC);
836 if (otp == NULL)
837 return -ENOMEM;
838
839 err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz);
840
841 sz = min_t(uint, sz, nwords);
842 memcpy(buf, otp, sz * 2);
843
844 kfree(otp);
845
846 /* Check CRC */
847 if (buf[0] == 0xffff)
848 /* The hardware thinks that an srom that starts with 0xffff
849 * is blank, regardless of the rest of the content, so declare
850 * it bad.
851 */
852 return -ENODATA;
853
854 /* fixup the endianness so crc8 will pass */
855 cpu_to_le16_buf(buf, sz);
856 if (crc8(brcms_srom_crc8_table, (u8 *) buf, sz * 2,
857 CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(brcms_srom_crc8_table))
858 err = -EIO;
859 else
860 /* now correct the endianness of the byte array */
861 le16_to_cpu_buf(buf, sz);
862
863 return err;
864}
865
866/*
867 * Initialize nonvolatile variable table from sprom.
868 * Return 0 on success, nonzero on error.
869 */
870int srom_var_init(struct si_pub *sih)
871{
872 u16 *srom;
873 u8 sromrev = 0;
874 u32 sr;
875 int err = 0;
876
877 /*
878 * Apply CRC over SROM content regardless SROM is present or not.
879 */
880 srom = kmalloc(SROM_MAX, GFP_ATOMIC);
881 if (!srom)
882 return -ENOMEM;
883
884 crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY);
885 if (ai_is_sprom_available(sih)) {
886 err = sprom_read_pci(sih, srom, SROM4_WORDS, true);
887
888 if (err == 0)
889 /* srom read and passed crc */
890 /* top word of sprom contains version and crc8 */
891 sromrev = srom[SROM4_CRCREV] & 0xff;
892 } else {
893 /* Use OTP if SPROM not available */
894 err = otp_read_pci(sih, srom, SROM4_WORDS);
895 if (err == 0)
896 /* OTP only contain SROM rev8/rev9 for now */
897 sromrev = srom[SROM4_CRCREV] & 0xff;
898 }
899
900 if (!err) {
901 struct si_info *sii = (struct si_info *)sih;
902
903 /* Bitmask for the sromrev */
904 sr = 1 << sromrev;
905
906 /*
907 * srom version check: Current valid versions: 8, 9
908 */
909 if ((sr & 0x300) == 0) {
910 err = -EINVAL;
911 goto errout;
912 }
913
914 INIT_LIST_HEAD(&sii->var_list);
915
916 /* parse SROM into name=value pairs. */
917 err = _initvars_srom_pci(sromrev, srom, &sii->var_list);
918 if (err)
919 srom_free_vars(sih);
920 }
921
922errout:
923 kfree(srom);
924 return err;
925}
926
927void srom_free_vars(struct si_pub *sih)
928{
929 struct si_info *sii;
930 struct brcms_srom_list_head *entry, *next;
931
932 sii = (struct si_info *)sih;
933 list_for_each_entry_safe(entry, next, &sii->var_list, var_list) {
934 list_del(&entry->var_list);
935 kfree(entry);
936 }
937}
938
939/*
940 * Search the name=value vars for a specific one and return its value.
941 * Returns NULL if not found.
942 */
943char *getvar(struct si_pub *sih, enum brcms_srom_id id)
944{
945 struct si_info *sii;
946 struct brcms_srom_list_head *entry;
947
948 sii = (struct si_info *)sih;
949
950 list_for_each_entry(entry, &sii->var_list, var_list)
951 if (entry->varid == id)
952 return &entry->buf[0];
953
954 /* nothing found */
955 return NULL;
956}
957
958/*
959 * Search the vars for a specific one and return its value as
960 * an integer. Returns 0 if not found.-
961 */
962int getintvar(struct si_pub *sih, enum brcms_srom_id id)
963{
964 struct si_info *sii;
965 struct brcms_srom_list_head *entry;
966 unsigned long res;
967
968 sii = (struct si_info *)sih;
969
970 list_for_each_entry(entry, &sii->var_list, var_list)
971 if (entry->varid == id) {
972 if (entry->var_type == BRCMS_SROM_SNUMBER ||
973 entry->var_type == BRCMS_SROM_UNUMBER)
974 return (int)entry->sval;
975 else if (!kstrtoul(&entry->buf[0], 0, &res))
976 return (int)res;
977 }
978
979 return 0;
980}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.h b/drivers/net/wireless/brcm80211/brcmsmac/srom.h
deleted file mode 100644
index f2a58f262c99..000000000000
--- a/drivers/net/wireless/brcm80211/brcmsmac/srom.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_SROM_H_
18#define _BRCM_SROM_H_
19
20#include "types.h"
21
22/* Prototypes */
23extern int srom_var_init(struct si_pub *sih);
24extern void srom_free_vars(struct si_pub *sih);
25
26extern int srom_read(struct si_pub *sih, uint bus, void *curmap,
27 uint byteoff, uint nbytes, u16 *buf, bool check_crc);
28
29#endif /* _BRCM_SROM_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
index d8f528eb180c..ed1d1aa71d2d 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
@@ -370,9 +370,11 @@ void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
370 370
371void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc) 371void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc)
372{ 372{
373 struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
374
373 /* get available rx/tx chains */ 375 /* get available rx/tx chains */
374 wlc->stf->hw_txchain = (u8) getintvar(wlc->hw->sih, BRCMS_SROM_TXCHAIN); 376 wlc->stf->hw_txchain = sprom->txchain;
375 wlc->stf->hw_rxchain = (u8) getintvar(wlc->hw->sih, BRCMS_SROM_RXCHAIN); 377 wlc->stf->hw_rxchain = sprom->rxchain;
376 378
377 /* these parameter are intended to be used for all PHY types */ 379 /* these parameter are intended to be used for all PHY types */
378 if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) { 380 if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 01dc44267317..e55ec6c8a920 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -31,6 +31,7 @@
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <net/mac80211.h>
34 35
35#include "iwl-dev.h" 36#include "iwl-dev.h"
36#include "iwl-io.h" 37#include "iwl-io.h"
@@ -273,9 +274,20 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
273 return; 274 return;
274 } 275 }
275 276
277 /*
278 * Possible situations when BT needs to take over for receive,
279 * at the same time where STA needs to response to AP's frame(s),
280 * reduce the tx power of the required response frames, by that,
281 * allow the concurrent BT receive & WiFi transmit
282 * (BT - ANT A, WiFi -ANT B), without interference to one another
283 *
284 * Reduced tx power apply to control frames only (ACK/Back/CTS)
285 * when indicated by the BT config command
286 */
276 basic.kill_ack_mask = priv->kill_ack_mask; 287 basic.kill_ack_mask = priv->kill_ack_mask;
277 basic.kill_cts_mask = priv->kill_cts_mask; 288 basic.kill_cts_mask = priv->kill_cts_mask;
278 basic.reduce_txpower = priv->reduced_txpower; 289 if (priv->reduced_txpower)
290 basic.reduce_txpower = IWLAGN_BT_REDUCED_TX_PWR;
279 basic.valid = priv->bt_valid; 291 basic.valid = priv->bt_valid;
280 292
281 /* 293 /*
@@ -589,13 +601,31 @@ static bool iwlagn_set_kill_msk(struct iwl_priv *priv,
589 return need_update; 601 return need_update;
590} 602}
591 603
604/*
605 * Upon RSSI changes, sends a bt config command with following changes
606 * 1. enable/disable "reduced control frames tx power
607 * 2. update the "kill)ack_mask" and "kill_cts_mask"
608 *
609 * If "reduced tx power" is enabled, uCode shall
610 * 1. ACK/Back/CTS rate shall reduced to 6Mbps
611 * 2. not use duplciate 20/40MHz mode
612 */
592static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv, 613static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv,
593 struct iwl_bt_uart_msg *uart_msg) 614 struct iwl_bt_uart_msg *uart_msg)
594{ 615{
595 bool need_update = false; 616 bool need_update = false;
617 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
618 int ave_rssi;
596 619
620 ave_rssi = ieee80211_ave_rssi(ctx->vif);
621 if (!ave_rssi) {
622 /* no rssi data, no changes to reduce tx power */
623 IWL_DEBUG_COEX(priv, "no rssi data available\n");
624 return need_update;
625 }
597 if (!priv->reduced_txpower && 626 if (!priv->reduced_txpower &&
598 !iwl_is_associated(priv, IWL_RXON_CTX_PAN) && 627 !iwl_is_associated(priv, IWL_RXON_CTX_PAN) &&
628 (ave_rssi > BT_ENABLE_REDUCED_TXPOWER_THRESHOLD) &&
599 (uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK | 629 (uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK |
600 BT_UART_MSG_FRAME3OBEX_MSK)) && 630 BT_UART_MSG_FRAME3OBEX_MSK)) &&
601 !(uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK | 631 !(uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK |
@@ -606,13 +636,14 @@ static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv,
606 need_update = true; 636 need_update = true;
607 } else if (priv->reduced_txpower && 637 } else if (priv->reduced_txpower &&
608 (iwl_is_associated(priv, IWL_RXON_CTX_PAN) || 638 (iwl_is_associated(priv, IWL_RXON_CTX_PAN) ||
639 (ave_rssi < BT_DISABLE_REDUCED_TXPOWER_THRESHOLD) ||
609 (uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK | 640 (uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK |
610 BT_UART_MSG_FRAME3SNIFF_MSK | BT_UART_MSG_FRAME3A2DP_MSK)) || 641 BT_UART_MSG_FRAME3SNIFF_MSK | BT_UART_MSG_FRAME3A2DP_MSK)) ||
611 !(uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK | 642 !(uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK |
612 BT_UART_MSG_FRAME3OBEX_MSK)))) { 643 BT_UART_MSG_FRAME3OBEX_MSK)))) {
613 /* disable reduced tx power */ 644 /* disable reduced tx power */
614 priv->reduced_txpower = false; 645 priv->reduced_txpower = false;
615 priv->bt_valid &= ~IWLAGN_BT_VALID_REDUCED_TX_PWR; 646 priv->bt_valid |= IWLAGN_BT_VALID_REDUCED_TX_PWR;
616 need_update = true; 647 need_update = true;
617 } 648 }
618 649
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 74fbee627306..0a3aa7c83003 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -61,6 +61,10 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
61 RXON_FILTER_ACCEPT_GRP_MSK; 61 RXON_FILTER_ACCEPT_GRP_MSK;
62 break; 62 break;
63 63
64 case NL80211_IFTYPE_MONITOR:
65 ctx->staging.dev_type = RXON_DEV_TYPE_SNIFFER;
66 break;
67
64 default: 68 default:
65 IWL_ERR(priv, "Unsupported interface type %d\n", 69 IWL_ERR(priv, "Unsupported interface type %d\n",
66 ctx->vif->type); 70 ctx->vif->type);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index f2e9f298a947..3366e2e2f00f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -590,11 +590,17 @@ turn_off:
590 spin_unlock_bh(&priv->sta_lock); 590 spin_unlock_bh(&priv->sta_lock);
591 591
592 if (test_bit(txq_id, priv->agg_q_alloc)) { 592 if (test_bit(txq_id, priv->agg_q_alloc)) {
593 /* If the transport didn't know that we wanted to start 593 /*
594 * agreggation, don't tell it that we want to stop them 594 * If the transport didn't know that we wanted to start
595 * agreggation, don't tell it that we want to stop them.
596 * This can happen when we don't get the addBA response on
597 * time, or we hadn't time to drain the AC queues.
595 */ 598 */
596 if (agg_state != IWL_AGG_STARTING) 599 if (agg_state == IWL_AGG_ON)
597 iwl_trans_tx_agg_disable(priv->trans, txq_id); 600 iwl_trans_tx_agg_disable(priv->trans, txq_id);
601 else
602 IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n",
603 agg_state);
598 iwlagn_dealloc_agg_txq(priv, txq_id); 604 iwlagn_dealloc_agg_txq(priv, txq_id);
599 } 605 }
600 606
@@ -1300,10 +1306,11 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1300 (u8 *) &ba_resp->sta_addr_lo32, 1306 (u8 *) &ba_resp->sta_addr_lo32,
1301 ba_resp->sta_id); 1307 ba_resp->sta_id);
1302 IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, " 1308 IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, "
1303 "scd_flow = %d, scd_ssn = %d\n", 1309 "scd_flow = %d, scd_ssn = %d sent:%d, acked:%d\n",
1304 ba_resp->tid, le16_to_cpu(ba_resp->seq_ctl), 1310 ba_resp->tid, le16_to_cpu(ba_resp->seq_ctl),
1305 (unsigned long long)le64_to_cpu(ba_resp->bitmap), 1311 (unsigned long long)le64_to_cpu(ba_resp->bitmap),
1306 scd_flow, ba_resp_scd_ssn); 1312 scd_flow, ba_resp_scd_ssn, ba_resp->txed,
1313 ba_resp->txed_2_done);
1307 1314
1308 /* Mark that the expected block-ack response arrived */ 1315 /* Mark that the expected block-ack response arrived */
1309 agg->wait_for_ba = false; 1316 agg->wait_for_ba = false;
@@ -1319,8 +1326,6 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1319 */ 1326 */
1320 ba_resp->txed = ba_resp->txed_2_done; 1327 ba_resp->txed = ba_resp->txed_2_done;
1321 } 1328 }
1322 IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
1323 ba_resp->txed, ba_resp->txed_2_done);
1324 1329
1325 priv->tid_data[sta_id][tid].next_reclaimed = ba_resp_scd_ssn; 1330 priv->tid_data[sta_id][tid].next_reclaimed = ba_resp_scd_ssn;
1326 1331
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 8d7637083fcf..ec36e2b020b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -603,7 +603,7 @@ void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
603 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; 603 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
604 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; 604 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
605 priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = 605 priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
606 BIT(NL80211_IFTYPE_ADHOC); 606 BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MONITOR);
607 priv->contexts[IWL_RXON_CTX_BSS].interface_modes = 607 priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
608 BIT(NL80211_IFTYPE_STATION); 608 BIT(NL80211_IFTYPE_STATION);
609 priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP; 609 priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 83a6930f3658..9af6a239b384 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1910,6 +1910,8 @@ enum iwl_bt_kill_idx {
1910 IWLAGN_BT_VALID_REDUCED_TX_PWR | \ 1910 IWLAGN_BT_VALID_REDUCED_TX_PWR | \
1911 IWLAGN_BT_VALID_3W_LUT) 1911 IWLAGN_BT_VALID_3W_LUT)
1912 1912
1913#define IWLAGN_BT_REDUCED_TX_PWR BIT(0)
1914
1913#define IWLAGN_BT_DECISION_LUT_SIZE 12 1915#define IWLAGN_BT_DECISION_LUT_SIZE 12
1914 1916
1915struct iwl_basic_bt_cmd { 1917struct iwl_basic_bt_cmd {
@@ -1923,6 +1925,10 @@ struct iwl_basic_bt_cmd {
1923 u8 bt3_timer_t2_value; 1925 u8 bt3_timer_t2_value;
1924 __le16 bt4_reaction_time; /* unused */ 1926 __le16 bt4_reaction_time; /* unused */
1925 __le32 bt3_lookup_table[IWLAGN_BT_DECISION_LUT_SIZE]; 1927 __le32 bt3_lookup_table[IWLAGN_BT_DECISION_LUT_SIZE];
1928 /*
1929 * bit 0: use reduced tx power for control frame
1930 * bit 1 - 7: reserved
1931 */
1926 u8 reduce_txpower; 1932 u8 reduce_txpower;
1927 u8 reserved; 1933 u8 reserved;
1928 __le16 valid; 1934 __le16 valid;
@@ -2272,7 +2278,6 @@ struct iwl_ssid_ie {
2272#define IWL_GOOD_CRC_TH_DISABLED 0 2278#define IWL_GOOD_CRC_TH_DISABLED 0
2273#define IWL_GOOD_CRC_TH_DEFAULT cpu_to_le16(1) 2279#define IWL_GOOD_CRC_TH_DEFAULT cpu_to_le16(1)
2274#define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff) 2280#define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff)
2275#define IWL_MAX_SCAN_SIZE 1024
2276#define IWL_MAX_CMD_SIZE 4096 2281#define IWL_MAX_CMD_SIZE 4096
2277 2282
2278/* 2283/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
index d33cc9cc7d3f..ab2f4d7500a4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c
+++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
@@ -150,6 +150,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
150 IEEE80211_HW_QUEUE_CONTROL | 150 IEEE80211_HW_QUEUE_CONTROL |
151 IEEE80211_HW_SUPPORTS_PS | 151 IEEE80211_HW_SUPPORTS_PS |
152 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 152 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
153 IEEE80211_HW_WANT_MONITOR_VIF |
153 IEEE80211_HW_SCAN_WHILE_IDLE; 154 IEEE80211_HW_SCAN_WHILE_IDLE;
154 155
155 hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE; 156 hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE;
@@ -223,8 +224,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
223 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 224 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
224 225
225 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; 226 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
226 /* we create the 802.11 header and a zero-length SSID element */ 227 /* we create the 802.11 header and a max-length SSID element */
227 hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2; 228 hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 34;
228 229
229 /* 230 /*
230 * We don't use all queues: 4 and 9 are unused and any 231 * We don't use all queues: 4 and 9 are unused and any
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 8352265dbc4b..544ddf17f5bd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -253,6 +253,8 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
253 253
254 IWL_DEBUG_POWER(priv, "numSkipDtim = %u, dtimPeriod = %d\n", 254 IWL_DEBUG_POWER(priv, "numSkipDtim = %u, dtimPeriod = %d\n",
255 skip, period); 255 skip, period);
256 /* The power level here is 0-4 (used as array index), but user expects
257 to see 1-5 (according to spec). */
256 IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1); 258 IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1);
257} 259}
258 260
@@ -308,10 +310,12 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
308 priv->power_data.debug_sleep_level_override, 310 priv->power_data.debug_sleep_level_override,
309 dtimper); 311 dtimper);
310 else { 312 else {
313 /* Note that the user parameter is 1-5 (according to spec),
314 but we pass 0-4 because it acts as an array index. */
311 if (iwlwifi_mod_params.power_level > IWL_POWER_INDEX_1 && 315 if (iwlwifi_mod_params.power_level > IWL_POWER_INDEX_1 &&
312 iwlwifi_mod_params.power_level <= IWL_POWER_INDEX_5) 316 iwlwifi_mod_params.power_level <= IWL_POWER_NUM)
313 iwl_static_sleep_cmd(priv, cmd, 317 iwl_static_sleep_cmd(priv, cmd,
314 iwlwifi_mod_params.power_level, dtimper); 318 iwlwifi_mod_params.power_level - 1, dtimper);
315 else 319 else
316 iwl_static_sleep_cmd(priv, cmd, 320 iwl_static_sleep_cmd(priv, cmd,
317 IWL_POWER_INDEX_1, dtimper); 321 IWL_POWER_INDEX_1, dtimper);
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index a8437a6bc18e..031d8e21f82f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -52,6 +52,7 @@
52#define IWL_PASSIVE_DWELL_TIME_52 (10) 52#define IWL_PASSIVE_DWELL_TIME_52 (10)
53#define IWL_PASSIVE_DWELL_BASE (100) 53#define IWL_PASSIVE_DWELL_BASE (100)
54#define IWL_CHANNEL_TUNE_TIME 5 54#define IWL_CHANNEL_TUNE_TIME 5
55#define MAX_SCAN_CHANNEL 50
55 56
56static int iwl_send_scan_abort(struct iwl_priv *priv) 57static int iwl_send_scan_abort(struct iwl_priv *priv)
57{ 58{
@@ -616,7 +617,8 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
616 */ 617 */
617 618
618static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta, 619static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
619 const u8 *ies, int ie_len, int left) 620 const u8 *ies, int ie_len, const u8 *ssid,
621 u8 ssid_len, int left)
620{ 622{
621 int len = 0; 623 int len = 0;
622 u8 *pos = NULL; 624 u8 *pos = NULL;
@@ -638,14 +640,18 @@ static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
638 /* ...next IE... */ 640 /* ...next IE... */
639 pos = &frame->u.probe_req.variable[0]; 641 pos = &frame->u.probe_req.variable[0];
640 642
641 /* fill in our indirect SSID IE */ 643 /* fill in our SSID IE */
642 left -= 2; 644 left -= ssid_len + 2;
643 if (left < 0) 645 if (left < 0)
644 return 0; 646 return 0;
645 *pos++ = WLAN_EID_SSID; 647 *pos++ = WLAN_EID_SSID;
646 *pos++ = 0; 648 *pos++ = ssid_len;
649 if (ssid && ssid_len) {
650 memcpy(pos, ssid, ssid_len);
651 pos += ssid_len;
652 }
647 653
648 len += 2; 654 len += ssid_len + 2;
649 655
650 if (WARN_ON(left < ie_len)) 656 if (WARN_ON(left < ie_len))
651 return len; 657 return len;
@@ -679,6 +685,15 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
679 u8 active_chains; 685 u8 active_chains;
680 u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; 686 u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
681 int ret; 687 int ret;
688 int scan_cmd_size = sizeof(struct iwl_scan_cmd) +
689 MAX_SCAN_CHANNEL * sizeof(struct iwl_scan_channel) +
690 priv->fw->ucode_capa.max_probe_length;
691 const u8 *ssid = NULL;
692 u8 ssid_len = 0;
693
694 if (WARN_ON_ONCE(priv->scan_request &&
695 priv->scan_request->n_channels > MAX_SCAN_CHANNEL))
696 return -EINVAL;
682 697
683 lockdep_assert_held(&priv->mutex); 698 lockdep_assert_held(&priv->mutex);
684 699
@@ -686,8 +701,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
686 ctx = iwl_rxon_ctx_from_vif(vif); 701 ctx = iwl_rxon_ctx_from_vif(vif);
687 702
688 if (!priv->scan_cmd) { 703 if (!priv->scan_cmd) {
689 priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) + 704 priv->scan_cmd = kmalloc(scan_cmd_size, GFP_KERNEL);
690 IWL_MAX_SCAN_SIZE, GFP_KERNEL);
691 if (!priv->scan_cmd) { 705 if (!priv->scan_cmd) {
692 IWL_DEBUG_SCAN(priv, 706 IWL_DEBUG_SCAN(priv,
693 "fail to allocate memory for scan\n"); 707 "fail to allocate memory for scan\n");
@@ -695,7 +709,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
695 } 709 }
696 } 710 }
697 scan = priv->scan_cmd; 711 scan = priv->scan_cmd;
698 memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE); 712 memset(scan, 0, scan_cmd_size);
699 713
700 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; 714 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
701 scan->quiet_time = IWL_ACTIVE_QUIET_TIME; 715 scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
@@ -746,10 +760,18 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
746 if (priv->scan_request->n_ssids) { 760 if (priv->scan_request->n_ssids) {
747 int i, p = 0; 761 int i, p = 0;
748 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); 762 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
749 for (i = 0; i < priv->scan_request->n_ssids; i++) { 763 /*
750 /* always does wildcard anyway */ 764 * The highest priority SSID is inserted to the
751 if (!priv->scan_request->ssids[i].ssid_len) 765 * probe request template.
752 continue; 766 */
767 ssid_len = priv->scan_request->ssids[0].ssid_len;
768 ssid = priv->scan_request->ssids[0].ssid;
769
770 /*
771 * Invert the order of ssids, the firmware will invert
772 * it back.
773 */
774 for (i = priv->scan_request->n_ssids - 1; i >= 1; i--) {
753 scan->direct_scan[p].id = WLAN_EID_SSID; 775 scan->direct_scan[p].id = WLAN_EID_SSID;
754 scan->direct_scan[p].len = 776 scan->direct_scan[p].len =
755 priv->scan_request->ssids[i].ssid_len; 777 priv->scan_request->ssids[i].ssid_len;
@@ -883,7 +905,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
883 vif->addr, 905 vif->addr,
884 priv->scan_request->ie, 906 priv->scan_request->ie,
885 priv->scan_request->ie_len, 907 priv->scan_request->ie_len,
886 IWL_MAX_SCAN_SIZE - sizeof(*scan)); 908 ssid, ssid_len,
909 scan_cmd_size - sizeof(*scan));
887 break; 910 break;
888 case IWL_SCAN_RADIO_RESET: 911 case IWL_SCAN_RADIO_RESET:
889 case IWL_SCAN_ROC: 912 case IWL_SCAN_ROC:
@@ -891,7 +914,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
891 cmd_len = iwl_fill_probe_req( 914 cmd_len = iwl_fill_probe_req(
892 (struct ieee80211_mgmt *)scan->data, 915 (struct ieee80211_mgmt *)scan->data,
893 iwl_bcast_addr, NULL, 0, 916 iwl_bcast_addr, NULL, 0,
894 IWL_MAX_SCAN_SIZE - sizeof(*scan)); 917 NULL, 0,
918 scan_cmd_size - sizeof(*scan));
895 break; 919 break;
896 default: 920 default:
897 BUG(); 921 BUG();
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 03c0c6b1372c..fb787df01666 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -746,6 +746,11 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
746 hwsim_check_sta_magic(txi->control.sta); 746 hwsim_check_sta_magic(txi->control.sta);
747 747
748 ieee80211_tx_info_clear_status(txi); 748 ieee80211_tx_info_clear_status(txi);
749
750 /* frame was transmitted at most favorable rate at first attempt */
751 txi->control.rates[0].count = 1;
752 txi->control.rates[1].idx = -1;
753
749 if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack) 754 if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack)
750 txi->flags |= IEEE80211_TX_STAT_ACK; 755 txi->flags |= IEEE80211_TX_STAT_ACK;
751 ieee80211_tx_status_irqsafe(hw, skb); 756 ieee80211_tx_status_irqsafe(hw, skb);
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index 5c1a46bf1e11..3f66ebb0a630 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -29,6 +29,8 @@ mwifiex-y += scan.o
29mwifiex-y += join.o 29mwifiex-y += join.o
30mwifiex-y += sta_ioctl.o 30mwifiex-y += sta_ioctl.o
31mwifiex-y += sta_cmd.o 31mwifiex-y += sta_cmd.o
32mwifiex-y += uap_cmd.o
33mwifiex-y += ie.o
32mwifiex-y += sta_cmdresp.o 34mwifiex-y += sta_cmdresp.o
33mwifiex-y += sta_event.o 35mwifiex-y += sta_event.o
34mwifiex-y += sta_tx.o 36mwifiex-y += sta_tx.o
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index c78ea873a63a..87671446e24b 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -20,6 +20,23 @@
20#include "cfg80211.h" 20#include "cfg80211.h"
21#include "main.h" 21#include "main.h"
22 22
23static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
24 {
25 .max = 1, .types = BIT(NL80211_IFTYPE_STATION),
26 },
27 {
28 .max = 1, .types = BIT(NL80211_IFTYPE_AP),
29 },
30};
31
32static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = {
33 .limits = mwifiex_ap_sta_limits,
34 .num_different_channels = 1,
35 .n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits),
36 .max_interfaces = MWIFIEX_MAX_BSS_NUM,
37 .beacon_int_infra_match = true,
38};
39
23/* 40/*
24 * This function maps the nl802.11 channel type into driver channel type. 41 * This function maps the nl802.11 channel type into driver channel type.
25 * 42 *
@@ -67,7 +84,7 @@ mwifiex_is_alg_wep(u32 cipher)
67/* 84/*
68 * This function retrieves the private structure from kernel wiphy structure. 85 * This function retrieves the private structure from kernel wiphy structure.
69 */ 86 */
70static void *mwifiex_cfg80211_get_priv(struct wiphy *wiphy) 87static void *mwifiex_cfg80211_get_adapter(struct wiphy *wiphy)
71{ 88{
72 return (void *) (*(unsigned long *) wiphy_priv(wiphy)); 89 return (void *) (*(unsigned long *) wiphy_priv(wiphy));
73} 90}
@@ -80,8 +97,10 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
80 u8 key_index, bool pairwise, const u8 *mac_addr) 97 u8 key_index, bool pairwise, const u8 *mac_addr)
81{ 98{
82 struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); 99 struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
100 const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
101 const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
83 102
84 if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) { 103 if (mwifiex_set_encode(priv, NULL, 0, key_index, peer_mac, 1)) {
85 wiphy_err(wiphy, "deleting the crypto keys\n"); 104 wiphy_err(wiphy, "deleting the crypto keys\n");
86 return -EFAULT; 105 return -EFAULT;
87 } 106 }
@@ -98,7 +117,8 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
98 enum nl80211_tx_power_setting type, 117 enum nl80211_tx_power_setting type,
99 int mbm) 118 int mbm)
100{ 119{
101 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 120 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
121 struct mwifiex_private *priv;
102 struct mwifiex_power_cfg power_cfg; 122 struct mwifiex_power_cfg power_cfg;
103 int dbm = MBM_TO_DBM(mbm); 123 int dbm = MBM_TO_DBM(mbm);
104 124
@@ -109,6 +129,8 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
109 power_cfg.is_power_auto = 1; 129 power_cfg.is_power_auto = 1;
110 } 130 }
111 131
132 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
133
112 return mwifiex_set_tx_power(priv, &power_cfg); 134 return mwifiex_set_tx_power(priv, &power_cfg);
113} 135}
114 136
@@ -148,7 +170,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
148 if (!priv->sec_info.wep_enabled) 170 if (!priv->sec_info.wep_enabled)
149 return 0; 171 return 0;
150 172
151 if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) { 173 if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) {
152 wiphy_err(wiphy, "set default Tx key index\n"); 174 wiphy_err(wiphy, "set default Tx key index\n");
153 return -EFAULT; 175 return -EFAULT;
154 } 176 }
@@ -165,9 +187,11 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
165 struct key_params *params) 187 struct key_params *params)
166{ 188{
167 struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); 189 struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
190 const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
191 const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
168 192
169 if (mwifiex_set_encode(priv, params->key, params->key_len, 193 if (mwifiex_set_encode(priv, params->key, params->key_len,
170 key_index, 0)) { 194 key_index, peer_mac, 0)) {
171 wiphy_err(wiphy, "crypto keys added\n"); 195 wiphy_err(wiphy, "crypto keys added\n");
172 return -EFAULT; 196 return -EFAULT;
173 } 197 }
@@ -192,13 +216,13 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
192 enum ieee80211_band band; 216 enum ieee80211_band band;
193 struct ieee80211_supported_band *sband; 217 struct ieee80211_supported_band *sband;
194 struct ieee80211_channel *ch; 218 struct ieee80211_channel *ch;
195 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 219 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
196 struct mwifiex_adapter *adapter = priv->adapter; 220 struct mwifiex_private *priv;
197 struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg; 221 struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg;
198 222
199 /* Set country code */ 223 /* Set country code */
200 domain_info->country_code[0] = priv->country_code[0]; 224 domain_info->country_code[0] = adapter->country_code[0];
201 domain_info->country_code[1] = priv->country_code[1]; 225 domain_info->country_code[1] = adapter->country_code[1];
202 domain_info->country_code[2] = ' '; 226 domain_info->country_code[2] = ' ';
203 227
204 band = mwifiex_band_to_radio_type(adapter->config_bands); 228 band = mwifiex_band_to_radio_type(adapter->config_bands);
@@ -250,6 +274,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
250 274
251 domain_info->no_of_triplet = no_of_triplet; 275 domain_info->no_of_triplet = no_of_triplet;
252 276
277 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
278
253 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, 279 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
254 HostCmd_ACT_GEN_SET, 0, NULL)) { 280 HostCmd_ACT_GEN_SET, 0, NULL)) {
255 wiphy_err(wiphy, "11D: setting domain info in FW\n"); 281 wiphy_err(wiphy, "11D: setting domain info in FW\n");
@@ -272,12 +298,12 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
272static int mwifiex_reg_notifier(struct wiphy *wiphy, 298static int mwifiex_reg_notifier(struct wiphy *wiphy,
273 struct regulatory_request *request) 299 struct regulatory_request *request)
274{ 300{
275 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 301 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
276 302
277 wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for domain" 303 wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for %c%c\n",
278 " %c%c\n", request->alpha2[0], request->alpha2[1]); 304 request->alpha2[0], request->alpha2[1]);
279 305
280 memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2)); 306 memcpy(adapter->country_code, request->alpha2, sizeof(request->alpha2));
281 307
282 switch (request->initiator) { 308 switch (request->initiator) {
283 case NL80211_REGDOM_SET_BY_DRIVER: 309 case NL80211_REGDOM_SET_BY_DRIVER:
@@ -361,33 +387,10 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
361 if (mwifiex_bss_set_channel(priv, &cfp)) 387 if (mwifiex_bss_set_channel(priv, &cfp))
362 return -EFAULT; 388 return -EFAULT;
363 389
364 return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); 390 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA)
365} 391 return mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
366
367/*
368 * CFG802.11 operation handler to set channel.
369 *
370 * This function can only be used when station is not connected.
371 */
372static int
373mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
374 struct ieee80211_channel *chan,
375 enum nl80211_channel_type channel_type)
376{
377 struct mwifiex_private *priv;
378
379 if (dev)
380 priv = mwifiex_netdev_get_priv(dev);
381 else 392 else
382 priv = mwifiex_cfg80211_get_priv(wiphy); 393 return mwifiex_uap_set_channel(priv, cfp.channel);
383
384 if (priv->media_connected) {
385 wiphy_err(wiphy, "This setting is valid only when station "
386 "is not connected\n");
387 return -EINVAL;
388 }
389
390 return mwifiex_set_rf_channel(priv, chan, channel_type);
391} 394}
392 395
393/* 396/*
@@ -399,18 +402,13 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
399static int 402static int
400mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) 403mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
401{ 404{
402 int ret;
403
404 if (frag_thr < MWIFIEX_FRAG_MIN_VALUE || 405 if (frag_thr < MWIFIEX_FRAG_MIN_VALUE ||
405 frag_thr > MWIFIEX_FRAG_MAX_VALUE) 406 frag_thr > MWIFIEX_FRAG_MAX_VALUE)
406 return -EINVAL; 407 frag_thr = MWIFIEX_FRAG_MAX_VALUE;
407
408 /* Send request to firmware */
409 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
410 HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
411 &frag_thr);
412 408
413 return ret; 409 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
410 HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
411 &frag_thr);
414} 412}
415 413
416/* 414/*
@@ -439,19 +437,85 @@ mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
439static int 437static int
440mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 438mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
441{ 439{
442 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 440 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
443 int ret = 0; 441 struct mwifiex_private *priv;
442 struct mwifiex_uap_bss_param *bss_cfg;
443 int ret, bss_started, i;
444
445 for (i = 0; i < adapter->priv_num; i++) {
446 priv = adapter->priv[i];
447
448 switch (priv->bss_role) {
449 case MWIFIEX_BSS_ROLE_UAP:
450 bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param),
451 GFP_KERNEL);
452 if (!bss_cfg)
453 return -ENOMEM;
454
455 mwifiex_set_sys_config_invalid_data(bss_cfg);
456
457 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
458 bss_cfg->rts_threshold = wiphy->rts_threshold;
459 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
460 bss_cfg->frag_threshold = wiphy->frag_threshold;
461 if (changed & WIPHY_PARAM_RETRY_LONG)
462 bss_cfg->retry_limit = wiphy->retry_long;
463
464 bss_started = priv->bss_started;
465
466 ret = mwifiex_send_cmd_sync(priv,
467 HostCmd_CMD_UAP_BSS_STOP,
468 HostCmd_ACT_GEN_SET, 0,
469 NULL);
470 if (ret) {
471 wiphy_err(wiphy, "Failed to stop the BSS\n");
472 kfree(bss_cfg);
473 return ret;
474 }
444 475
445 if (changed & WIPHY_PARAM_RTS_THRESHOLD) { 476 ret = mwifiex_send_cmd_async(priv,
446 ret = mwifiex_set_rts(priv, wiphy->rts_threshold); 477 HostCmd_CMD_UAP_SYS_CONFIG,
447 if (ret) 478 HostCmd_ACT_GEN_SET,
448 return ret; 479 UAP_BSS_PARAMS_I, bss_cfg);
449 }
450 480
451 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) 481 kfree(bss_cfg);
452 ret = mwifiex_set_frag(priv, wiphy->frag_threshold);
453 482
454 return ret; 483 if (ret) {
484 wiphy_err(wiphy, "Failed to set bss config\n");
485 return ret;
486 }
487
488 if (!bss_started)
489 break;
490
491 ret = mwifiex_send_cmd_async(priv,
492 HostCmd_CMD_UAP_BSS_START,
493 HostCmd_ACT_GEN_SET, 0,
494 NULL);
495 if (ret) {
496 wiphy_err(wiphy, "Failed to start BSS\n");
497 return ret;
498 }
499
500 break;
501 case MWIFIEX_BSS_ROLE_STA:
502 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
503 ret = mwifiex_set_rts(priv,
504 wiphy->rts_threshold);
505 if (ret)
506 return ret;
507 }
508 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
509 ret = mwifiex_set_frag(priv,
510 wiphy->frag_threshold);
511 if (ret)
512 return ret;
513 }
514 break;
515 }
516 }
517
518 return 0;
455} 519}
456 520
457/* 521/*
@@ -466,31 +530,59 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
466 int ret; 530 int ret;
467 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 531 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
468 532
469 if (priv->bss_mode == type) { 533 switch (dev->ieee80211_ptr->iftype) {
470 wiphy_warn(wiphy, "already set to required type\n");
471 return 0;
472 }
473
474 priv->bss_mode = type;
475
476 switch (type) {
477 case NL80211_IFTYPE_ADHOC: 534 case NL80211_IFTYPE_ADHOC:
478 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC; 535 switch (type) {
479 wiphy_dbg(wiphy, "info: setting interface type to adhoc\n"); 536 case NL80211_IFTYPE_STATION:
537 break;
538 case NL80211_IFTYPE_UNSPECIFIED:
539 wiphy_warn(wiphy, "%s: kept type as IBSS\n", dev->name);
540 case NL80211_IFTYPE_ADHOC: /* This shouldn't happen */
541 return 0;
542 case NL80211_IFTYPE_AP:
543 default:
544 wiphy_err(wiphy, "%s: changing to %d not supported\n",
545 dev->name, type);
546 return -EOPNOTSUPP;
547 }
480 break; 548 break;
481 case NL80211_IFTYPE_STATION: 549 case NL80211_IFTYPE_STATION:
482 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; 550 switch (type) {
483 wiphy_dbg(wiphy, "info: setting interface type to managed\n"); 551 case NL80211_IFTYPE_ADHOC:
552 break;
553 case NL80211_IFTYPE_UNSPECIFIED:
554 wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name);
555 case NL80211_IFTYPE_STATION: /* This shouldn't happen */
556 return 0;
557 case NL80211_IFTYPE_AP:
558 default:
559 wiphy_err(wiphy, "%s: changing to %d not supported\n",
560 dev->name, type);
561 return -EOPNOTSUPP;
562 }
563 break;
564 case NL80211_IFTYPE_AP:
565 switch (type) {
566 case NL80211_IFTYPE_UNSPECIFIED:
567 wiphy_warn(wiphy, "%s: kept type as AP\n", dev->name);
568 case NL80211_IFTYPE_AP: /* This shouldn't happen */
569 return 0;
570 case NL80211_IFTYPE_ADHOC:
571 case NL80211_IFTYPE_STATION:
572 default:
573 wiphy_err(wiphy, "%s: changing to %d not supported\n",
574 dev->name, type);
575 return -EOPNOTSUPP;
576 }
484 break; 577 break;
485 case NL80211_IFTYPE_UNSPECIFIED:
486 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
487 wiphy_dbg(wiphy, "info: setting interface type to auto\n");
488 return 0;
489 default: 578 default:
490 wiphy_err(wiphy, "unknown interface type: %d\n", type); 579 wiphy_err(wiphy, "%s: unknown iftype: %d\n",
491 return -EINVAL; 580 dev->name, dev->ieee80211_ptr->iftype);
581 return -EOPNOTSUPP;
492 } 582 }
493 583
584 dev->ieee80211_ptr->iftype = type;
585 priv->bss_mode = type;
494 mwifiex_deauthenticate(priv, NULL); 586 mwifiex_deauthenticate(priv, NULL);
495 587
496 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; 588 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
@@ -804,6 +896,90 @@ static int mwifiex_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
804 return 0; 896 return 0;
805} 897}
806 898
899/* cfg80211 operation handler for stop ap.
900 * Function stops BSS running at uAP interface.
901 */
902static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
903{
904 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
905
906 if (mwifiex_del_mgmt_ies(priv))
907 wiphy_err(wiphy, "Failed to delete mgmt IEs!\n");
908
909 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
910 HostCmd_ACT_GEN_SET, 0, NULL)) {
911 wiphy_err(wiphy, "Failed to stop the BSS\n");
912 return -1;
913 }
914
915 return 0;
916}
917
918/* cfg80211 operation handler for start_ap.
919 * Function sets beacon period, DTIM period, SSID and security into
920 * AP config structure.
921 * AP is configured with these settings and BSS is started.
922 */
923static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
924 struct net_device *dev,
925 struct cfg80211_ap_settings *params)
926{
927 struct mwifiex_uap_bss_param *bss_cfg;
928 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
929
930 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP)
931 return -1;
932 if (mwifiex_set_mgmt_ies(priv, params))
933 return -1;
934
935 bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL);
936 if (!bss_cfg)
937 return -ENOMEM;
938
939 mwifiex_set_sys_config_invalid_data(bss_cfg);
940
941 if (params->beacon_interval)
942 bss_cfg->beacon_period = params->beacon_interval;
943 if (params->dtim_period)
944 bss_cfg->dtim_period = params->dtim_period;
945
946 if (params->ssid && params->ssid_len) {
947 memcpy(bss_cfg->ssid.ssid, params->ssid, params->ssid_len);
948 bss_cfg->ssid.ssid_len = params->ssid_len;
949 }
950
951 if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
952 kfree(bss_cfg);
953 wiphy_err(wiphy, "Failed to parse secuirty parameters!\n");
954 return -1;
955 }
956
957 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
958 HostCmd_ACT_GEN_SET, 0, NULL)) {
959 wiphy_err(wiphy, "Failed to stop the BSS\n");
960 kfree(bss_cfg);
961 return -1;
962 }
963
964 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG,
965 HostCmd_ACT_GEN_SET,
966 UAP_BSS_PARAMS_I, bss_cfg)) {
967 wiphy_err(wiphy, "Failed to set the SSID\n");
968 kfree(bss_cfg);
969 return -1;
970 }
971
972 kfree(bss_cfg);
973
974 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_BSS_START,
975 HostCmd_ACT_GEN_SET, 0, NULL)) {
976 wiphy_err(wiphy, "Failed to start the BSS\n");
977 return -1;
978 }
979
980 return 0;
981}
982
807/* 983/*
808 * CFG802.11 operation handler for disconnection request. 984 * CFG802.11 operation handler for disconnection request.
809 * 985 *
@@ -923,7 +1099,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
923 priv->wep_key_curr_index = 0; 1099 priv->wep_key_curr_index = 0;
924 priv->sec_info.encryption_mode = 0; 1100 priv->sec_info.encryption_mode = 0;
925 priv->sec_info.is_authtype_auto = 0; 1101 priv->sec_info.is_authtype_auto = 0;
926 ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); 1102 ret = mwifiex_set_encode(priv, NULL, 0, 0, NULL, 1);
927 1103
928 if (mode == NL80211_IFTYPE_ADHOC) { 1104 if (mode == NL80211_IFTYPE_ADHOC) {
929 /* "privacy" is set only for ad-hoc mode */ 1105 /* "privacy" is set only for ad-hoc mode */
@@ -971,7 +1147,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
971 " with key len %d\n", sme->key_len); 1147 " with key len %d\n", sme->key_len);
972 priv->wep_key_curr_index = sme->key_idx; 1148 priv->wep_key_curr_index = sme->key_idx;
973 ret = mwifiex_set_encode(priv, sme->key, sme->key_len, 1149 ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
974 sme->key_idx, 0); 1150 sme->key_idx, NULL, 0);
975 } 1151 }
976 } 1152 }
977done: 1153done:
@@ -1050,6 +1226,11 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1050 goto done; 1226 goto done;
1051 } 1227 }
1052 1228
1229 if (priv->bss_mode == NL80211_IFTYPE_AP) {
1230 wiphy_err(wiphy, "skip association request for AP interface\n");
1231 goto done;
1232 }
1233
1053 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", 1234 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
1054 (char *) sme->ssid, sme->bssid); 1235 (char *) sme->ssid, sme->bssid);
1055 1236
@@ -1283,15 +1464,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1283 u32 *flags, 1464 u32 *flags,
1284 struct vif_params *params) 1465 struct vif_params *params)
1285{ 1466{
1286 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 1467 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
1287 struct mwifiex_adapter *adapter; 1468 struct mwifiex_private *priv;
1288 struct net_device *dev; 1469 struct net_device *dev;
1289 void *mdev_priv; 1470 void *mdev_priv;
1471 struct wireless_dev *wdev;
1290 1472
1291 if (!priv)
1292 return NULL;
1293
1294 adapter = priv->adapter;
1295 if (!adapter) 1473 if (!adapter)
1296 return NULL; 1474 return NULL;
1297 1475
@@ -1299,12 +1477,21 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1299 case NL80211_IFTYPE_UNSPECIFIED: 1477 case NL80211_IFTYPE_UNSPECIFIED:
1300 case NL80211_IFTYPE_STATION: 1478 case NL80211_IFTYPE_STATION:
1301 case NL80211_IFTYPE_ADHOC: 1479 case NL80211_IFTYPE_ADHOC:
1480 priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
1302 if (priv->bss_mode) { 1481 if (priv->bss_mode) {
1303 wiphy_err(wiphy, "cannot create multiple" 1482 wiphy_err(wiphy,
1304 " station/adhoc interfaces\n"); 1483 "cannot create multiple sta/adhoc ifaces\n");
1305 return NULL; 1484 return NULL;
1306 } 1485 }
1307 1486
1487 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1488 if (!wdev)
1489 return NULL;
1490
1491 wdev->wiphy = wiphy;
1492 priv->wdev = wdev;
1493 wdev->iftype = NL80211_IFTYPE_STATION;
1494
1308 if (type == NL80211_IFTYPE_UNSPECIFIED) 1495 if (type == NL80211_IFTYPE_UNSPECIFIED)
1309 priv->bss_mode = NL80211_IFTYPE_STATION; 1496 priv->bss_mode = NL80211_IFTYPE_STATION;
1310 else 1497 else
@@ -1312,11 +1499,36 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1312 1499
1313 priv->bss_type = MWIFIEX_BSS_TYPE_STA; 1500 priv->bss_type = MWIFIEX_BSS_TYPE_STA;
1314 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; 1501 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
1315 priv->bss_priority = 0; 1502 priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
1316 priv->bss_role = MWIFIEX_BSS_ROLE_STA; 1503 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
1317 priv->bss_num = 0; 1504 priv->bss_num = 0;
1318 1505
1319 break; 1506 break;
1507 case NL80211_IFTYPE_AP:
1508 priv = adapter->priv[MWIFIEX_BSS_TYPE_UAP];
1509
1510 if (priv->bss_mode) {
1511 wiphy_err(wiphy, "Can't create multiple AP interfaces");
1512 return NULL;
1513 }
1514
1515 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1516 if (!wdev)
1517 return NULL;
1518
1519 priv->wdev = wdev;
1520 wdev->wiphy = wiphy;
1521 wdev->iftype = NL80211_IFTYPE_AP;
1522
1523 priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
1524 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
1525 priv->bss_priority = MWIFIEX_BSS_ROLE_UAP;
1526 priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
1527 priv->bss_started = 0;
1528 priv->bss_num = 0;
1529 priv->bss_mode = type;
1530
1531 break;
1320 default: 1532 default:
1321 wiphy_err(wiphy, "type not supported\n"); 1533 wiphy_err(wiphy, "type not supported\n");
1322 return NULL; 1534 return NULL;
@@ -1329,6 +1541,15 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1329 goto error; 1541 goto error;
1330 } 1542 }
1331 1543
1544 mwifiex_init_priv_params(priv, dev);
1545 priv->netdev = dev;
1546
1547 mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
1548
1549 if (adapter->config_bands & BAND_A)
1550 mwifiex_setup_ht_caps(
1551 &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
1552
1332 dev_net_set(dev, wiphy_net(wiphy)); 1553 dev_net_set(dev, wiphy_net(wiphy));
1333 dev->ieee80211_ptr = priv->wdev; 1554 dev->ieee80211_ptr = priv->wdev;
1334 dev->ieee80211_ptr->iftype = priv->bss_mode; 1555 dev->ieee80211_ptr->iftype = priv->bss_mode;
@@ -1343,9 +1564,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1343 mdev_priv = netdev_priv(dev); 1564 mdev_priv = netdev_priv(dev);
1344 *((unsigned long *) mdev_priv) = (unsigned long) priv; 1565 *((unsigned long *) mdev_priv) = (unsigned long) priv;
1345 1566
1346 priv->netdev = dev;
1347 mwifiex_init_priv_params(priv, dev);
1348
1349 SET_NETDEV_DEV(dev, adapter->dev); 1567 SET_NETDEV_DEV(dev, adapter->dev);
1350 1568
1351 /* Register network device */ 1569 /* Register network device */
@@ -1417,7 +1635,6 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
1417 .get_station = mwifiex_cfg80211_get_station, 1635 .get_station = mwifiex_cfg80211_get_station,
1418 .dump_station = mwifiex_cfg80211_dump_station, 1636 .dump_station = mwifiex_cfg80211_dump_station,
1419 .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params, 1637 .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params,
1420 .set_channel = mwifiex_cfg80211_set_channel,
1421 .join_ibss = mwifiex_cfg80211_join_ibss, 1638 .join_ibss = mwifiex_cfg80211_join_ibss,
1422 .leave_ibss = mwifiex_cfg80211_leave_ibss, 1639 .leave_ibss = mwifiex_cfg80211_leave_ibss,
1423 .add_key = mwifiex_cfg80211_add_key, 1640 .add_key = mwifiex_cfg80211_add_key,
@@ -1426,6 +1643,8 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
1426 .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, 1643 .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
1427 .set_tx_power = mwifiex_cfg80211_set_tx_power, 1644 .set_tx_power = mwifiex_cfg80211_set_tx_power,
1428 .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask, 1645 .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask,
1646 .start_ap = mwifiex_cfg80211_start_ap,
1647 .stop_ap = mwifiex_cfg80211_stop_ap,
1429 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config, 1648 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
1430}; 1649};
1431 1650
@@ -1436,82 +1655,67 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
1436 * default parameters and handler function pointers, and finally 1655 * default parameters and handler function pointers, and finally
1437 * registers the device. 1656 * registers the device.
1438 */ 1657 */
1439int mwifiex_register_cfg80211(struct mwifiex_private *priv) 1658
1659int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
1440{ 1660{
1441 int ret; 1661 int ret;
1442 void *wdev_priv; 1662 void *wdev_priv;
1443 struct wireless_dev *wdev; 1663 struct wiphy *wiphy;
1444 struct ieee80211_sta_ht_cap *ht_info; 1664 struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
1445 u8 *country_code; 1665 u8 *country_code;
1446 1666
1447 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 1667 /* create a new wiphy for use with cfg80211 */
1448 if (!wdev) { 1668 wiphy = wiphy_new(&mwifiex_cfg80211_ops,
1449 dev_err(priv->adapter->dev, "%s: allocating wireless device\n", 1669 sizeof(struct mwifiex_adapter *));
1450 __func__); 1670 if (!wiphy) {
1451 return -ENOMEM; 1671 dev_err(adapter->dev, "%s: creating new wiphy\n", __func__);
1452 }
1453 wdev->wiphy =
1454 wiphy_new(&mwifiex_cfg80211_ops,
1455 sizeof(struct mwifiex_private *));
1456 if (!wdev->wiphy) {
1457 kfree(wdev);
1458 return -ENOMEM; 1672 return -ENOMEM;
1459 } 1673 }
1460 wdev->iftype = NL80211_IFTYPE_STATION; 1674 wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
1461 wdev->wiphy->max_scan_ssids = 10; 1675 wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
1462 wdev->wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN; 1676 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1463 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1677 BIT(NL80211_IFTYPE_ADHOC) |
1464 BIT(NL80211_IFTYPE_ADHOC); 1678 BIT(NL80211_IFTYPE_AP);
1465 1679
1466 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; 1680 wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
1467 ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap; 1681 if (adapter->config_bands & BAND_A)
1468 mwifiex_setup_ht_caps(ht_info, priv); 1682 wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
1469 1683 else
1470 if (priv->adapter->config_bands & BAND_A) { 1684 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
1471 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; 1685
1472 ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap; 1686 wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta;
1473 mwifiex_setup_ht_caps(ht_info, priv); 1687 wiphy->n_iface_combinations = 1;
1474 } else {
1475 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
1476 }
1477 1688
1478 /* Initialize cipher suits */ 1689 /* Initialize cipher suits */
1479 wdev->wiphy->cipher_suites = mwifiex_cipher_suites; 1690 wiphy->cipher_suites = mwifiex_cipher_suites;
1480 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); 1691 wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
1481 1692
1482 memcpy(wdev->wiphy->perm_addr, priv->curr_addr, ETH_ALEN); 1693 memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
1483 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 1694 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1695 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_CUSTOM_REGULATORY;
1484 1696
1485 /* Reserve space for mwifiex specific private data for BSS */ 1697 /* Reserve space for mwifiex specific private data for BSS */
1486 wdev->wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); 1698 wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
1487
1488 wdev->wiphy->reg_notifier = mwifiex_reg_notifier;
1489 1699
1490 /* Set struct mwifiex_private pointer in wiphy_priv */ 1700 wiphy->reg_notifier = mwifiex_reg_notifier;
1491 wdev_priv = wiphy_priv(wdev->wiphy);
1492 1701
1493 *(unsigned long *) wdev_priv = (unsigned long) priv; 1702 /* Set struct mwifiex_adapter pointer in wiphy_priv */
1703 wdev_priv = wiphy_priv(wiphy);
1704 *(unsigned long *)wdev_priv = (unsigned long)adapter;
1494 1705
1495 set_wiphy_dev(wdev->wiphy, (struct device *) priv->adapter->dev); 1706 set_wiphy_dev(wiphy, (struct device *)priv->adapter->dev);
1496 1707
1497 ret = wiphy_register(wdev->wiphy); 1708 ret = wiphy_register(wiphy);
1498 if (ret < 0) { 1709 if (ret < 0) {
1499 dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", 1710 dev_err(adapter->dev,
1500 __func__); 1711 "%s: wiphy_register failed: %d\n", __func__, ret);
1501 wiphy_free(wdev->wiphy); 1712 wiphy_free(wiphy);
1502 kfree(wdev);
1503 return ret; 1713 return ret;
1504 } else {
1505 dev_dbg(priv->adapter->dev,
1506 "info: successfully registered wiphy device\n");
1507 } 1714 }
1508
1509 country_code = mwifiex_11d_code_2_region(priv->adapter->region_code); 1715 country_code = mwifiex_11d_code_2_region(priv->adapter->region_code);
1510 if (country_code && regulatory_hint(wdev->wiphy, country_code)) 1716 if (country_code && regulatory_hint(wiphy, country_code))
1511 dev_err(priv->adapter->dev, 1717 dev_err(adapter->dev, "regulatory_hint() failed\n");
1512 "%s: regulatory_hint failed\n", __func__);
1513
1514 priv->wdev = wdev;
1515 1718
1719 adapter->wiphy = wiphy;
1516 return ret; 1720 return ret;
1517} 1721}
diff --git a/drivers/net/wireless/mwifiex/cfg80211.h b/drivers/net/wireless/mwifiex/cfg80211.h
index 76c76c60438b..c5848934f111 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.h
+++ b/drivers/net/wireless/mwifiex/cfg80211.h
@@ -24,6 +24,6 @@
24 24
25#include "main.h" 25#include "main.h"
26 26
27int mwifiex_register_cfg80211(struct mwifiex_private *); 27int mwifiex_register_cfg80211(struct mwifiex_adapter *);
28 28
29#endif 29#endif
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 1710beffb93a..51e023ec1de4 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -440,6 +440,11 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
440 do_gettimeofday(&tstamp); 440 do_gettimeofday(&tstamp);
441 dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n", 441 dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n",
442 tstamp.tv_sec, tstamp.tv_usec, eventcause); 442 tstamp.tv_sec, tstamp.tv_usec, eventcause);
443 } else {
444 /* Handle PS_SLEEP/AWAKE events on STA */
445 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
446 if (!priv)
447 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
443 } 448 }
444 449
445 ret = mwifiex_process_sta_event(priv); 450 ret = mwifiex_process_sta_event(priv);
@@ -540,8 +545,20 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
540 545
541 /* Prepare command */ 546 /* Prepare command */
542 if (cmd_no) { 547 if (cmd_no) {
543 ret = mwifiex_sta_prepare_cmd(priv, cmd_no, cmd_action, 548 switch (cmd_no) {
544 cmd_oid, data_buf, cmd_ptr); 549 case HostCmd_CMD_UAP_SYS_CONFIG:
550 case HostCmd_CMD_UAP_BSS_START:
551 case HostCmd_CMD_UAP_BSS_STOP:
552 ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action,
553 cmd_oid, data_buf,
554 cmd_ptr);
555 break;
556 default:
557 ret = mwifiex_sta_prepare_cmd(priv, cmd_no, cmd_action,
558 cmd_oid, data_buf,
559 cmd_ptr);
560 break;
561 }
545 } else { 562 } else {
546 ret = mwifiex_cmd_host_cmd(priv, cmd_ptr, data_buf); 563 ret = mwifiex_cmd_host_cmd(priv, cmd_ptr, data_buf);
547 cmd_node->cmd_flag |= CMD_F_HOSTCMD; 564 cmd_node->cmd_flag |= CMD_F_HOSTCMD;
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index d04aba4131dc..f918f66e5e27 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -28,7 +28,7 @@
28#include <linux/ieee80211.h> 28#include <linux/ieee80211.h>
29 29
30 30
31#define MWIFIEX_MAX_BSS_NUM (1) 31#define MWIFIEX_MAX_BSS_NUM (2)
32 32
33#define MWIFIEX_MIN_DATA_HEADER_LEN 36 /* sizeof(mwifiex_txpd) 33#define MWIFIEX_MIN_DATA_HEADER_LEN 36 /* sizeof(mwifiex_txpd)
34 * + 4 byte alignment 34 * + 4 byte alignment
@@ -55,11 +55,17 @@
55#define MWIFIEX_RX_DATA_BUF_SIZE (4 * 1024) 55#define MWIFIEX_RX_DATA_BUF_SIZE (4 * 1024)
56#define MWIFIEX_RX_CMD_BUF_SIZE (2 * 1024) 56#define MWIFIEX_RX_CMD_BUF_SIZE (2 * 1024)
57 57
58#define MAX_BEACON_PERIOD (4000)
59#define MIN_BEACON_PERIOD (50)
60#define MAX_DTIM_PERIOD (100)
61#define MIN_DTIM_PERIOD (1)
62
58#define MWIFIEX_RTS_MIN_VALUE (0) 63#define MWIFIEX_RTS_MIN_VALUE (0)
59#define MWIFIEX_RTS_MAX_VALUE (2347) 64#define MWIFIEX_RTS_MAX_VALUE (2347)
60#define MWIFIEX_FRAG_MIN_VALUE (256) 65#define MWIFIEX_FRAG_MIN_VALUE (256)
61#define MWIFIEX_FRAG_MAX_VALUE (2346) 66#define MWIFIEX_FRAG_MAX_VALUE (2346)
62 67
68#define MWIFIEX_RETRY_LIMIT 14
63#define MWIFIEX_SDIO_BLOCK_SIZE 256 69#define MWIFIEX_SDIO_BLOCK_SIZE 256
64 70
65#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) 71#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0)
@@ -92,6 +98,11 @@ struct mwifiex_fw_image {
92 u32 fw_len; 98 u32 fw_len;
93}; 99};
94 100
101struct mwifiex_802_11_ssid {
102 u32 ssid_len;
103 u8 ssid[IEEE80211_MAX_SSID_LEN];
104};
105
95struct mwifiex_wait_queue { 106struct mwifiex_wait_queue {
96 wait_queue_head_t wait; 107 wait_queue_head_t wait;
97 int status; 108 int status;
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 5f6adeb9b950..9f674bbebe65 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -93,6 +93,20 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
93 93
94#define CAL_SNR(RSSI, NF) ((s16)((s16)(RSSI)-(s16)(NF))) 94#define CAL_SNR(RSSI, NF) ((s16)((s16)(RSSI)-(s16)(NF)))
95 95
96#define UAP_BSS_PARAMS_I 0
97#define UAP_CUSTOM_IE_I 1
98#define MWIFIEX_AUTO_IDX_MASK 0xffff
99#define MWIFIEX_DELETE_MASK 0x0000
100#define MGMT_MASK_ASSOC_REQ 0x01
101#define MGMT_MASK_REASSOC_REQ 0x04
102#define MGMT_MASK_ASSOC_RESP 0x02
103#define MGMT_MASK_REASSOC_RESP 0x08
104#define MGMT_MASK_PROBE_REQ 0x10
105#define MGMT_MASK_PROBE_RESP 0x20
106#define MGMT_MASK_BEACON 0x100
107
108#define TLV_TYPE_UAP_SSID 0x0000
109
96#define PROPRIETARY_TLV_BASE_ID 0x0100 110#define PROPRIETARY_TLV_BASE_ID 0x0100
97#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0) 111#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0)
98#define TLV_TYPE_CHANLIST (PROPRIETARY_TLV_BASE_ID + 1) 112#define TLV_TYPE_CHANLIST (PROPRIETARY_TLV_BASE_ID + 1)
@@ -104,14 +118,26 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
104#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19) 118#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
105#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22) 119#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22)
106#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31) 120#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
121#define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32)
107#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) 122#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42)
123#define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44)
124#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45)
125#define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51)
126#define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60)
127#define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64)
128#define TLV_TYPE_UAP_AKMP (PROPRIETARY_TLV_BASE_ID + 65)
129#define TLV_TYPE_UAP_FRAG_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 70)
108#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82) 130#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82)
109#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83) 131#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83)
110#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84) 132#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84)
133#define TLV_TYPE_UAP_RETRY_LIMIT (PROPRIETARY_TLV_BASE_ID + 93)
111#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94) 134#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94)
135#define TLV_TYPE_UAP_MGMT_FRAME (PROPRIETARY_TLV_BASE_ID + 104)
112#define TLV_TYPE_MGMT_IE (PROPRIETARY_TLV_BASE_ID + 105) 136#define TLV_TYPE_MGMT_IE (PROPRIETARY_TLV_BASE_ID + 105)
113#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113) 137#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113)
114#define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114) 138#define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114)
139#define TLV_TYPE_PWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 145)
140#define TLV_TYPE_GWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 146)
115 141
116#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 142#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048
117 143
@@ -209,6 +235,9 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
209#define HostCmd_CMD_RSSI_INFO 0x00a4 235#define HostCmd_CMD_RSSI_INFO 0x00a4
210#define HostCmd_CMD_FUNC_INIT 0x00a9 236#define HostCmd_CMD_FUNC_INIT 0x00a9
211#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa 237#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa
238#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0
239#define HostCmd_CMD_UAP_BSS_START 0x00b1
240#define HostCmd_CMD_UAP_BSS_STOP 0x00b2
212#define HostCmd_CMD_11N_CFG 0x00cd 241#define HostCmd_CMD_11N_CFG 0x00cd
213#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce 242#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce
214#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf 243#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf
@@ -223,6 +252,19 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
223#define HostCmd_CMD_SET_BSS_MODE 0x00f7 252#define HostCmd_CMD_SET_BSS_MODE 0x00f7
224#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa 253#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa
225 254
255#define PROTOCOL_NO_SECURITY 0x01
256#define PROTOCOL_STATIC_WEP 0x02
257#define PROTOCOL_WPA 0x08
258#define PROTOCOL_WPA2 0x20
259#define PROTOCOL_WPA2_MIXED 0x28
260#define PROTOCOL_EAP 0x40
261#define KEY_MGMT_NONE 0x04
262#define KEY_MGMT_PSK 0x02
263#define KEY_MGMT_EAP 0x01
264#define CIPHER_TKIP 0x04
265#define CIPHER_AES_CCMP 0x08
266#define VALID_CIPHER_BITMAP 0x0c
267
226enum ENH_PS_MODES { 268enum ENH_PS_MODES {
227 EN_PS = 1, 269 EN_PS = 1,
228 DIS_PS = 2, 270 DIS_PS = 2,
@@ -313,15 +355,20 @@ enum ENH_PS_MODES {
313#define EVENT_DATA_SNR_HIGH 0x00000027 355#define EVENT_DATA_SNR_HIGH 0x00000027
314#define EVENT_LINK_QUALITY 0x00000028 356#define EVENT_LINK_QUALITY 0x00000028
315#define EVENT_PORT_RELEASE 0x0000002b 357#define EVENT_PORT_RELEASE 0x0000002b
358#define EVENT_UAP_STA_DEAUTH 0x0000002c
359#define EVENT_UAP_STA_ASSOC 0x0000002d
360#define EVENT_UAP_BSS_START 0x0000002e
316#define EVENT_PRE_BEACON_LOST 0x00000031 361#define EVENT_PRE_BEACON_LOST 0x00000031
317#define EVENT_ADDBA 0x00000033 362#define EVENT_ADDBA 0x00000033
318#define EVENT_DELBA 0x00000034 363#define EVENT_DELBA 0x00000034
319#define EVENT_BA_STREAM_TIEMOUT 0x00000037 364#define EVENT_BA_STREAM_TIEMOUT 0x00000037
320#define EVENT_AMSDU_AGGR_CTRL 0x00000042 365#define EVENT_AMSDU_AGGR_CTRL 0x00000042
366#define EVENT_UAP_BSS_IDLE 0x00000043
367#define EVENT_UAP_BSS_ACTIVE 0x00000044
321#define EVENT_WEP_ICV_ERR 0x00000046 368#define EVENT_WEP_ICV_ERR 0x00000046
322#define EVENT_HS_ACT_REQ 0x00000047 369#define EVENT_HS_ACT_REQ 0x00000047
323#define EVENT_BW_CHANGE 0x00000048 370#define EVENT_BW_CHANGE 0x00000048
324 371#define EVENT_UAP_MIC_COUNTERMEASURES 0x0000004c
325#define EVENT_HOSTWAKE_STAIE 0x0000004d 372#define EVENT_HOSTWAKE_STAIE 0x0000004d
326 373
327#define EVENT_ID_MASK 0xffff 374#define EVENT_ID_MASK 0xffff
@@ -1103,6 +1150,101 @@ struct host_cmd_ds_802_11_eeprom_access {
1103 u8 value; 1150 u8 value;
1104} __packed; 1151} __packed;
1105 1152
1153struct host_cmd_tlv {
1154 __le16 type;
1155 __le16 len;
1156} __packed;
1157
1158struct mwifiex_assoc_event {
1159 u8 sta_addr[ETH_ALEN];
1160 __le16 type;
1161 __le16 len;
1162 __le16 frame_control;
1163 __le16 cap_info;
1164 __le16 listen_interval;
1165 u8 data[0];
1166} __packed;
1167
1168struct host_cmd_ds_sys_config {
1169 __le16 action;
1170 u8 tlv[0];
1171};
1172
1173struct host_cmd_tlv_akmp {
1174 struct host_cmd_tlv tlv;
1175 __le16 key_mgmt;
1176 __le16 key_mgmt_operation;
1177} __packed;
1178
1179struct host_cmd_tlv_pwk_cipher {
1180 struct host_cmd_tlv tlv;
1181 __le16 proto;
1182 u8 cipher;
1183 u8 reserved;
1184} __packed;
1185
1186struct host_cmd_tlv_gwk_cipher {
1187 struct host_cmd_tlv tlv;
1188 u8 cipher;
1189 u8 reserved;
1190} __packed;
1191
1192struct host_cmd_tlv_passphrase {
1193 struct host_cmd_tlv tlv;
1194 u8 passphrase[0];
1195} __packed;
1196
1197struct host_cmd_tlv_auth_type {
1198 struct host_cmd_tlv tlv;
1199 u8 auth_type;
1200} __packed;
1201
1202struct host_cmd_tlv_encrypt_protocol {
1203 struct host_cmd_tlv tlv;
1204 __le16 proto;
1205} __packed;
1206
1207struct host_cmd_tlv_ssid {
1208 struct host_cmd_tlv tlv;
1209 u8 ssid[0];
1210} __packed;
1211
1212struct host_cmd_tlv_beacon_period {
1213 struct host_cmd_tlv tlv;
1214 __le16 period;
1215} __packed;
1216
1217struct host_cmd_tlv_dtim_period {
1218 struct host_cmd_tlv tlv;
1219 u8 period;
1220} __packed;
1221
1222struct host_cmd_tlv_frag_threshold {
1223 struct host_cmd_tlv tlv;
1224 __le16 frag_thr;
1225} __packed;
1226
1227struct host_cmd_tlv_rts_threshold {
1228 struct host_cmd_tlv tlv;
1229 __le16 rts_thr;
1230} __packed;
1231
1232struct host_cmd_tlv_retry_limit {
1233 struct host_cmd_tlv tlv;
1234 u8 limit;
1235} __packed;
1236
1237struct host_cmd_tlv_mac_addr {
1238 struct host_cmd_tlv tlv;
1239 u8 mac_addr[ETH_ALEN];
1240} __packed;
1241
1242struct host_cmd_tlv_channel_band {
1243 struct host_cmd_tlv tlv;
1244 u8 band_config;
1245 u8 channel;
1246} __packed;
1247
1106struct host_cmd_ds_802_11_rf_channel { 1248struct host_cmd_ds_802_11_rf_channel {
1107 __le16 action; 1249 __le16 action;
1108 __le16 current_channel; 1250 __le16 current_channel;
@@ -1167,6 +1309,20 @@ struct host_cmd_ds_802_11_subsc_evt {
1167 __le16 events; 1309 __le16 events;
1168} __packed; 1310} __packed;
1169 1311
1312struct mwifiex_ie {
1313 __le16 ie_index;
1314 __le16 mgmt_subtype_mask;
1315 __le16 ie_length;
1316 u8 ie_buffer[IEEE_MAX_IE_SIZE];
1317} __packed;
1318
1319#define MAX_MGMT_IE_INDEX 16
1320struct mwifiex_ie_list {
1321 __le16 type;
1322 __le16 len;
1323 struct mwifiex_ie ie_list[MAX_MGMT_IE_INDEX];
1324} __packed;
1325
1170struct host_cmd_ds_command { 1326struct host_cmd_ds_command {
1171 __le16 command; 1327 __le16 command;
1172 __le16 size; 1328 __le16 size;
@@ -1217,6 +1373,7 @@ struct host_cmd_ds_command {
1217 struct host_cmd_ds_pcie_details pcie_host_spec; 1373 struct host_cmd_ds_pcie_details pcie_host_spec;
1218 struct host_cmd_ds_802_11_eeprom_access eeprom; 1374 struct host_cmd_ds_802_11_eeprom_access eeprom;
1219 struct host_cmd_ds_802_11_subsc_evt subsc_evt; 1375 struct host_cmd_ds_802_11_subsc_evt subsc_evt;
1376 struct host_cmd_ds_sys_config uap_sys_config;
1220 } params; 1377 } params;
1221} __packed; 1378} __packed;
1222 1379
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
new file mode 100644
index 000000000000..ceb82cd749cc
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -0,0 +1,396 @@
1/*
2 * Marvell Wireless LAN device driver: management IE handling- setting and
3 * deleting IE.
4 *
5 * Copyright (C) 2012, Marvell International Ltd.
6 *
7 * This software file (the "File") is distributed by Marvell International
8 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
9 * (the "License"). You may use, redistribute and/or modify this File in
10 * accordance with the terms and conditions of the License, a copy of which
11 * is available by writing to the Free Software Foundation, Inc.,
12 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
13 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
14 *
15 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
18 * this warranty disclaimer.
19 */
20
21#include "main.h"
22
23/* This function checks if current IE index is used by any on other interface.
24 * Return: -1: yes, current IE index is used by someone else.
25 * 0: no, current IE index is NOT used by other interface.
26 */
27static int
28mwifiex_ie_index_used_by_other_intf(struct mwifiex_private *priv, u16 idx)
29{
30 int i;
31 struct mwifiex_adapter *adapter = priv->adapter;
32 struct mwifiex_ie *ie;
33
34 for (i = 0; i < adapter->priv_num; i++) {
35 if (adapter->priv[i] != priv) {
36 ie = &adapter->priv[i]->mgmt_ie[idx];
37 if (ie->mgmt_subtype_mask && ie->ie_length)
38 return -1;
39 }
40 }
41
42 return 0;
43}
44
45/* Get unused IE index. This index will be used for setting new IE */
46static int
47mwifiex_ie_get_autoidx(struct mwifiex_private *priv, u16 subtype_mask,
48 struct mwifiex_ie *ie, u16 *index)
49{
50 u16 mask, len, i;
51
52 for (i = 0; i < priv->adapter->max_mgmt_ie_index; i++) {
53 mask = le16_to_cpu(priv->mgmt_ie[i].mgmt_subtype_mask);
54 len = le16_to_cpu(priv->mgmt_ie[i].ie_length) +
55 le16_to_cpu(ie->ie_length);
56
57 if (mask == MWIFIEX_AUTO_IDX_MASK)
58 continue;
59
60 if (mask == subtype_mask) {
61 if (len > IEEE_MAX_IE_SIZE)
62 continue;
63
64 *index = i;
65 return 0;
66 }
67
68 if (!priv->mgmt_ie[i].ie_length) {
69 if (mwifiex_ie_index_used_by_other_intf(priv, i))
70 continue;
71
72 *index = i;
73 return 0;
74 }
75 }
76
77 return -1;
78}
79
80/* This function prepares IE data buffer for command to be sent to FW */
81static int
82mwifiex_update_autoindex_ies(struct mwifiex_private *priv,
83 struct mwifiex_ie_list *ie_list)
84{
85 u16 travel_len, index, mask;
86 s16 input_len;
87 struct mwifiex_ie *ie;
88 u8 *tmp;
89
90 input_len = le16_to_cpu(ie_list->len);
91 travel_len = sizeof(struct host_cmd_tlv);
92
93 ie_list->len = 0;
94
95 while (input_len > 0) {
96 ie = (struct mwifiex_ie *)(((u8 *)ie_list) + travel_len);
97 input_len -= le16_to_cpu(ie->ie_length) + MWIFIEX_IE_HDR_SIZE;
98 travel_len += le16_to_cpu(ie->ie_length) + MWIFIEX_IE_HDR_SIZE;
99
100 index = le16_to_cpu(ie->ie_index);
101 mask = le16_to_cpu(ie->mgmt_subtype_mask);
102
103 if (index == MWIFIEX_AUTO_IDX_MASK) {
104 /* automatic addition */
105 if (mwifiex_ie_get_autoidx(priv, mask, ie, &index))
106 return -1;
107 if (index == MWIFIEX_AUTO_IDX_MASK)
108 return -1;
109
110 tmp = (u8 *)&priv->mgmt_ie[index].ie_buffer;
111 tmp += le16_to_cpu(priv->mgmt_ie[index].ie_length);
112 memcpy(tmp, &ie->ie_buffer, le16_to_cpu(ie->ie_length));
113 le16_add_cpu(&priv->mgmt_ie[index].ie_length,
114 le16_to_cpu(ie->ie_length));
115 priv->mgmt_ie[index].ie_index = cpu_to_le16(index);
116 priv->mgmt_ie[index].mgmt_subtype_mask =
117 cpu_to_le16(mask);
118
119 ie->ie_index = cpu_to_le16(index);
120 ie->ie_length = priv->mgmt_ie[index].ie_length;
121 memcpy(&ie->ie_buffer, &priv->mgmt_ie[index].ie_buffer,
122 le16_to_cpu(priv->mgmt_ie[index].ie_length));
123 } else {
124 if (mask != MWIFIEX_DELETE_MASK)
125 return -1;
126 /*
127 * Check if this index is being used on any
128 * other interface.
129 */
130 if (mwifiex_ie_index_used_by_other_intf(priv, index))
131 return -1;
132
133 ie->ie_length = 0;
134 memcpy(&priv->mgmt_ie[index], ie,
135 sizeof(struct mwifiex_ie));
136 }
137
138 le16_add_cpu(&ie_list->len,
139 le16_to_cpu(priv->mgmt_ie[index].ie_length) +
140 MWIFIEX_IE_HDR_SIZE);
141 }
142
143 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
144 return mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG,
145 HostCmd_ACT_GEN_SET,
146 UAP_CUSTOM_IE_I, ie_list);
147
148 return 0;
149}
150
151/* Copy individual custom IEs for beacon, probe response and assoc response
152 * and prepare single structure for IE setting.
153 * This function also updates allocated IE indices from driver.
154 */
155static int
156mwifiex_update_uap_custom_ie(struct mwifiex_private *priv,
157 struct mwifiex_ie *beacon_ie, u16 *beacon_idx,
158 struct mwifiex_ie *pr_ie, u16 *probe_idx,
159 struct mwifiex_ie *ar_ie, u16 *assoc_idx)
160{
161 struct mwifiex_ie_list *ap_custom_ie;
162 u8 *pos;
163 u16 len;
164 int ret;
165
166 ap_custom_ie = kzalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
167 if (!ap_custom_ie)
168 return -ENOMEM;
169
170 ap_custom_ie->type = cpu_to_le16(TLV_TYPE_MGMT_IE);
171 pos = (u8 *)ap_custom_ie->ie_list;
172
173 if (beacon_ie) {
174 len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE +
175 le16_to_cpu(beacon_ie->ie_length);
176 memcpy(pos, beacon_ie, len);
177 pos += len;
178 le16_add_cpu(&ap_custom_ie->len, len);
179 }
180 if (pr_ie) {
181 len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE +
182 le16_to_cpu(pr_ie->ie_length);
183 memcpy(pos, pr_ie, len);
184 pos += len;
185 le16_add_cpu(&ap_custom_ie->len, len);
186 }
187 if (ar_ie) {
188 len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE +
189 le16_to_cpu(ar_ie->ie_length);
190 memcpy(pos, ar_ie, len);
191 pos += len;
192 le16_add_cpu(&ap_custom_ie->len, len);
193 }
194
195 ret = mwifiex_update_autoindex_ies(priv, ap_custom_ie);
196
197 pos = (u8 *)(&ap_custom_ie->ie_list[0].ie_index);
198 if (beacon_ie && *beacon_idx == MWIFIEX_AUTO_IDX_MASK) {
199 /* save beacon ie index after auto-indexing */
200 *beacon_idx = le16_to_cpu(ap_custom_ie->ie_list[0].ie_index);
201 len = sizeof(*beacon_ie) - IEEE_MAX_IE_SIZE +
202 le16_to_cpu(beacon_ie->ie_length);
203 pos += len;
204 }
205 if (pr_ie && le16_to_cpu(pr_ie->ie_index) == MWIFIEX_AUTO_IDX_MASK) {
206 /* save probe resp ie index after auto-indexing */
207 *probe_idx = *((u16 *)pos);
208 len = sizeof(*pr_ie) - IEEE_MAX_IE_SIZE +
209 le16_to_cpu(pr_ie->ie_length);
210 pos += len;
211 }
212 if (ar_ie && le16_to_cpu(ar_ie->ie_index) == MWIFIEX_AUTO_IDX_MASK)
213 /* save assoc resp ie index after auto-indexing */
214 *assoc_idx = *((u16 *)pos);
215
216 return ret;
217}
218
219/* This function parses different IEs- Tail IEs, beacon IEs, probe response IEs,
220 * association response IEs from cfg80211_ap_settings function and sets these IE
221 * to FW.
222 */
223int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
224 struct cfg80211_ap_settings *params)
225{
226 struct mwifiex_ie *beacon_ie = NULL, *pr_ie = NULL;
227 struct mwifiex_ie *ar_ie = NULL, *rsn_ie = NULL;
228 struct ieee_types_header *ie = NULL;
229 u16 beacon_idx = MWIFIEX_AUTO_IDX_MASK, pr_idx = MWIFIEX_AUTO_IDX_MASK;
230 u16 ar_idx = MWIFIEX_AUTO_IDX_MASK, rsn_idx = MWIFIEX_AUTO_IDX_MASK;
231 u16 mask;
232 int ret = 0;
233
234 if (params->beacon.tail && params->beacon.tail_len) {
235 ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, params->beacon.tail,
236 params->beacon.tail_len);
237 if (ie) {
238 rsn_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
239 if (!rsn_ie)
240 return -ENOMEM;
241
242 rsn_ie->ie_index = cpu_to_le16(rsn_idx);
243 mask = MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP |
244 MGMT_MASK_ASSOC_RESP;
245 rsn_ie->mgmt_subtype_mask = cpu_to_le16(mask);
246 rsn_ie->ie_length = cpu_to_le16(ie->len + 2);
247 memcpy(rsn_ie->ie_buffer, ie, ie->len + 2);
248
249 if (mwifiex_update_uap_custom_ie(priv, rsn_ie, &rsn_idx,
250 NULL, NULL,
251 NULL, NULL)) {
252 ret = -1;
253 goto done;
254 }
255
256 priv->rsn_idx = rsn_idx;
257 }
258 }
259
260 if (params->beacon.beacon_ies && params->beacon.beacon_ies_len) {
261 beacon_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
262 if (!beacon_ie) {
263 ret = -ENOMEM;
264 goto done;
265 }
266
267 beacon_ie->ie_index = cpu_to_le16(beacon_idx);
268 beacon_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON);
269 beacon_ie->ie_length =
270 cpu_to_le16(params->beacon.beacon_ies_len);
271 memcpy(beacon_ie->ie_buffer, params->beacon.beacon_ies,
272 params->beacon.beacon_ies_len);
273 }
274
275 if (params->beacon.proberesp_ies && params->beacon.proberesp_ies_len) {
276 pr_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
277 if (!pr_ie) {
278 ret = -ENOMEM;
279 goto done;
280 }
281
282 pr_ie->ie_index = cpu_to_le16(pr_idx);
283 pr_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_PROBE_RESP);
284 pr_ie->ie_length =
285 cpu_to_le16(params->beacon.proberesp_ies_len);
286 memcpy(pr_ie->ie_buffer, params->beacon.proberesp_ies,
287 params->beacon.proberesp_ies_len);
288 }
289
290 if (params->beacon.assocresp_ies && params->beacon.assocresp_ies_len) {
291 ar_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
292 if (!ar_ie) {
293 ret = -ENOMEM;
294 goto done;
295 }
296
297 ar_ie->ie_index = cpu_to_le16(ar_idx);
298 mask = MGMT_MASK_ASSOC_RESP | MGMT_MASK_REASSOC_RESP;
299 ar_ie->mgmt_subtype_mask = cpu_to_le16(mask);
300 ar_ie->ie_length =
301 cpu_to_le16(params->beacon.assocresp_ies_len);
302 memcpy(ar_ie->ie_buffer, params->beacon.assocresp_ies,
303 params->beacon.assocresp_ies_len);
304 }
305
306 if (beacon_ie || pr_ie || ar_ie) {
307 ret = mwifiex_update_uap_custom_ie(priv, beacon_ie,
308 &beacon_idx, pr_ie,
309 &pr_idx, ar_ie, &ar_idx);
310 if (ret)
311 goto done;
312 }
313
314 priv->beacon_idx = beacon_idx;
315 priv->proberesp_idx = pr_idx;
316 priv->assocresp_idx = ar_idx;
317
318done:
319 kfree(beacon_ie);
320 kfree(pr_ie);
321 kfree(ar_ie);
322 kfree(rsn_ie);
323
324 return ret;
325}
326
327/* This function removes management IE set */
328int mwifiex_del_mgmt_ies(struct mwifiex_private *priv)
329{
330 struct mwifiex_ie *beacon_ie = NULL, *pr_ie = NULL;
331 struct mwifiex_ie *ar_ie = NULL, *rsn_ie = NULL;
332 int ret = 0;
333
334 if (priv->rsn_idx != MWIFIEX_AUTO_IDX_MASK) {
335 rsn_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
336 if (!rsn_ie)
337 return -ENOMEM;
338
339 rsn_ie->ie_index = cpu_to_le16(priv->rsn_idx);
340 rsn_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK);
341 rsn_ie->ie_length = 0;
342 if (mwifiex_update_uap_custom_ie(priv, rsn_ie, &priv->rsn_idx,
343 NULL, &priv->proberesp_idx,
344 NULL, &priv->assocresp_idx)) {
345 ret = -1;
346 goto done;
347 }
348
349 priv->rsn_idx = MWIFIEX_AUTO_IDX_MASK;
350 }
351
352 if (priv->beacon_idx != MWIFIEX_AUTO_IDX_MASK) {
353 beacon_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
354 if (!beacon_ie) {
355 ret = -ENOMEM;
356 goto done;
357 }
358 beacon_ie->ie_index = cpu_to_le16(priv->beacon_idx);
359 beacon_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK);
360 beacon_ie->ie_length = 0;
361 }
362 if (priv->proberesp_idx != MWIFIEX_AUTO_IDX_MASK) {
363 pr_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
364 if (!pr_ie) {
365 ret = -ENOMEM;
366 goto done;
367 }
368 pr_ie->ie_index = cpu_to_le16(priv->proberesp_idx);
369 pr_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK);
370 pr_ie->ie_length = 0;
371 }
372 if (priv->assocresp_idx != MWIFIEX_AUTO_IDX_MASK) {
373 ar_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
374 if (!ar_ie) {
375 ret = -ENOMEM;
376 goto done;
377 }
378 ar_ie->ie_index = cpu_to_le16(priv->assocresp_idx);
379 ar_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK);
380 ar_ie->ie_length = 0;
381 }
382
383 if (beacon_ie || pr_ie || ar_ie)
384 ret = mwifiex_update_uap_custom_ie(priv,
385 beacon_ie, &priv->beacon_idx,
386 pr_ie, &priv->proberesp_idx,
387 ar_ie, &priv->assocresp_idx);
388
389done:
390 kfree(beacon_ie);
391 kfree(pr_ie);
392 kfree(ar_ie);
393 kfree(rsn_ie);
394
395 return ret;
396}
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index d440c3eb640b..c1cb004db913 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -279,6 +279,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
279 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); 279 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
280 adapter->arp_filter_size = 0; 280 adapter->arp_filter_size = 0;
281 adapter->channel_type = NL80211_CHAN_HT20; 281 adapter->channel_type = NL80211_CHAN_HT20;
282 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
282} 283}
283 284
284/* 285/*
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index f0f95524e96b..e6be6ee75951 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -62,6 +62,36 @@ enum {
62 BAND_AN = 16, 62 BAND_AN = 16,
63}; 63};
64 64
65#define MWIFIEX_WPA_PASSHPHRASE_LEN 64
66struct wpa_param {
67 u8 pairwise_cipher_wpa;
68 u8 pairwise_cipher_wpa2;
69 u8 group_cipher;
70 u32 length;
71 u8 passphrase[MWIFIEX_WPA_PASSHPHRASE_LEN];
72};
73
74#define KEY_MGMT_ON_HOST 0x03
75#define MWIFIEX_AUTH_MODE_AUTO 0xFF
76#define BAND_CONFIG_MANUAL 0x00
77struct mwifiex_uap_bss_param {
78 u8 channel;
79 u8 band_cfg;
80 u16 rts_threshold;
81 u16 frag_threshold;
82 u8 retry_limit;
83 struct mwifiex_802_11_ssid ssid;
84 u8 bcast_ssid_ctl;
85 u8 radio_ctl;
86 u8 dtim_period;
87 u16 beacon_period;
88 u16 auth_mode;
89 u16 protocol;
90 u16 key_mgmt;
91 u16 key_mgmt_operation;
92 struct wpa_param wpa_cfg;
93};
94
65enum { 95enum {
66 ADHOC_IDLE, 96 ADHOC_IDLE,
67 ADHOC_STARTED, 97 ADHOC_STARTED,
@@ -269,6 +299,8 @@ struct mwifiex_ds_read_eeprom {
269 299
270#define IEEE_MAX_IE_SIZE 256 300#define IEEE_MAX_IE_SIZE 256
271 301
302#define MWIFIEX_IE_HDR_SIZE (sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE)
303
272struct mwifiex_ds_misc_gen_ie { 304struct mwifiex_ds_misc_gen_ie {
273 u32 type; 305 u32 type;
274 u32 len; 306 u32 len;
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 8a390982463e..d6b4fb04011f 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1374,22 +1374,28 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
1374 * 1374 *
1375 * In case of infra made, it sends deauthentication request, and 1375 * In case of infra made, it sends deauthentication request, and
1376 * in case of ad-hoc mode, a stop network request is sent to the firmware. 1376 * in case of ad-hoc mode, a stop network request is sent to the firmware.
1377 * In AP mode, a command to stop bss is sent to firmware.
1377 */ 1378 */
1378int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac) 1379int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
1379{ 1380{
1380 int ret = 0; 1381 if (!priv->media_connected)
1382 return 0;
1381 1383
1382 if (priv->media_connected) { 1384 switch (priv->bss_mode) {
1383 if (priv->bss_mode == NL80211_IFTYPE_STATION) { 1385 case NL80211_IFTYPE_STATION:
1384 ret = mwifiex_deauthenticate_infra(priv, mac); 1386 return mwifiex_deauthenticate_infra(priv, mac);
1385 } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { 1387 case NL80211_IFTYPE_ADHOC:
1386 ret = mwifiex_send_cmd_sync(priv, 1388 return mwifiex_send_cmd_sync(priv,
1387 HostCmd_CMD_802_11_AD_HOC_STOP, 1389 HostCmd_CMD_802_11_AD_HOC_STOP,
1388 HostCmd_ACT_GEN_SET, 0, NULL); 1390 HostCmd_ACT_GEN_SET, 0, NULL);
1389 } 1391 case NL80211_IFTYPE_AP:
1392 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
1393 HostCmd_ACT_GEN_SET, 0, NULL);
1394 default:
1395 break;
1390 } 1396 }
1391 1397
1392 return ret; 1398 return 0;
1393} 1399}
1394EXPORT_SYMBOL_GPL(mwifiex_deauthenticate); 1400EXPORT_SYMBOL_GPL(mwifiex_deauthenticate);
1395 1401
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index be0f0e583f75..3192855c31c0 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -64,17 +64,17 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
64 64
65 adapter->priv_num = 0; 65 adapter->priv_num = 0;
66 66
67 /* Allocate memory for private structure */ 67 for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) {
68 adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL); 68 /* Allocate memory for private structure */
69 if (!adapter->priv[0]) { 69 adapter->priv[i] =
70 dev_err(adapter->dev, 70 kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL);
71 "%s: failed to alloc priv[0]\n", __func__); 71 if (!adapter->priv[i])
72 goto error; 72 goto error;
73 }
74
75 adapter->priv_num++;
76 73
77 adapter->priv[0]->adapter = adapter; 74 adapter->priv[i]->adapter = adapter;
75 adapter->priv[i]->bss_priority = i;
76 adapter->priv_num++;
77 }
78 mwifiex_init_lock_list(adapter); 78 mwifiex_init_lock_list(adapter);
79 79
80 init_timer(&adapter->cmd_timer); 80 init_timer(&adapter->cmd_timer);
@@ -349,19 +349,26 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
349 if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) 349 if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
350 goto done; 350 goto done;
351 351
352 priv = adapter->priv[0]; 352 priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
353 if (mwifiex_register_cfg80211(priv) != 0) { 353 if (mwifiex_register_cfg80211(adapter)) {
354 dev_err(adapter->dev, "cannot register with cfg80211\n"); 354 dev_err(adapter->dev, "cannot register with cfg80211\n");
355 goto err_init_fw; 355 goto err_init_fw;
356 } 356 }
357 357
358 rtnl_lock(); 358 rtnl_lock();
359 /* Create station interface by default */ 359 /* Create station interface by default */
360 if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d", 360 if (!mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d",
361 NL80211_IFTYPE_STATION, NULL, NULL)) { 361 NL80211_IFTYPE_STATION, NULL, NULL)) {
362 dev_err(adapter->dev, "cannot create default STA interface\n"); 362 dev_err(adapter->dev, "cannot create default STA interface\n");
363 goto err_add_intf; 363 goto err_add_intf;
364 } 364 }
365
366 /* Create AP interface by default */
367 if (!mwifiex_add_virtual_intf(adapter->wiphy, "uap%d",
368 NL80211_IFTYPE_AP, NULL, NULL)) {
369 dev_err(adapter->dev, "cannot create default AP interface\n");
370 goto err_add_intf;
371 }
365 rtnl_unlock(); 372 rtnl_unlock();
366 373
367 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1); 374 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
@@ -369,7 +376,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
369 goto done; 376 goto done;
370 377
371err_add_intf: 378err_add_intf:
372 mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev); 379 mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev);
373 rtnl_unlock(); 380 rtnl_unlock();
374err_init_fw: 381err_init_fw:
375 pr_debug("info: %s: unregister device\n", __func__); 382 pr_debug("info: %s: unregister device\n", __func__);
@@ -633,6 +640,12 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
633 priv->current_key_index = 0; 640 priv->current_key_index = 0;
634 priv->media_connected = false; 641 priv->media_connected = false;
635 memset(&priv->nick_name, 0, sizeof(priv->nick_name)); 642 memset(&priv->nick_name, 0, sizeof(priv->nick_name));
643 memset(priv->mgmt_ie, 0,
644 sizeof(struct mwifiex_ie) * MAX_MGMT_IE_INDEX);
645 priv->beacon_idx = MWIFIEX_AUTO_IDX_MASK;
646 priv->proberesp_idx = MWIFIEX_AUTO_IDX_MASK;
647 priv->assocresp_idx = MWIFIEX_AUTO_IDX_MASK;
648 priv->rsn_idx = MWIFIEX_AUTO_IDX_MASK;
636 priv->num_tx_timeout = 0; 649 priv->num_tx_timeout = 0;
637 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); 650 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
638} 651}
@@ -830,19 +843,21 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
830 843
831 rtnl_lock(); 844 rtnl_lock();
832 if (priv->wdev && priv->netdev) 845 if (priv->wdev && priv->netdev)
833 mwifiex_del_virtual_intf(priv->wdev->wiphy, 846 mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev);
834 priv->netdev);
835 rtnl_unlock(); 847 rtnl_unlock();
836 } 848 }
837 849
838 priv = adapter->priv[0]; 850 priv = adapter->priv[0];
839 if (!priv) 851 if (!priv || !priv->wdev)
840 goto exit_remove; 852 goto exit_remove;
841 853
842 if (priv->wdev) { 854 wiphy_unregister(priv->wdev->wiphy);
843 wiphy_unregister(priv->wdev->wiphy); 855 wiphy_free(priv->wdev->wiphy);
844 wiphy_free(priv->wdev->wiphy); 856
845 kfree(priv->wdev); 857 for (i = 0; i < adapter->priv_num; i++) {
858 priv = adapter->priv[i];
859 if (priv)
860 kfree(priv->wdev);
846 } 861 }
847 862
848 mwifiex_terminate_workqueue(adapter); 863 mwifiex_terminate_workqueue(adapter);
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 324ad390cacd..bd3b0bf94b9e 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -116,6 +116,7 @@ enum {
116#define MAX_FREQUENCY_BAND_BG 2484 116#define MAX_FREQUENCY_BAND_BG 2484
117 117
118#define MWIFIEX_EVENT_HEADER_LEN 4 118#define MWIFIEX_EVENT_HEADER_LEN 4
119#define MWIFIEX_UAP_EVENT_EXTRA_HEADER 2
119 120
120#define MWIFIEX_TYPE_LEN 4 121#define MWIFIEX_TYPE_LEN 4
121#define MWIFIEX_USB_TYPE_CMD 0xF00DFACE 122#define MWIFIEX_USB_TYPE_CMD 0xF00DFACE
@@ -370,6 +371,7 @@ struct mwifiex_private {
370 u8 bss_role; 371 u8 bss_role;
371 u8 bss_priority; 372 u8 bss_priority;
372 u8 bss_num; 373 u8 bss_num;
374 u8 bss_started;
373 u8 frame_type; 375 u8 frame_type;
374 u8 curr_addr[ETH_ALEN]; 376 u8 curr_addr[ETH_ALEN];
375 u8 media_connected; 377 u8 media_connected;
@@ -470,12 +472,16 @@ struct mwifiex_private {
470 struct cfg80211_scan_request *scan_request; 472 struct cfg80211_scan_request *scan_request;
471 struct mwifiex_user_scan_cfg *user_scan_cfg; 473 struct mwifiex_user_scan_cfg *user_scan_cfg;
472 u8 cfg_bssid[6]; 474 u8 cfg_bssid[6];
473 u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
474 struct wps wps; 475 struct wps wps;
475 u8 scan_block; 476 u8 scan_block;
476 s32 cqm_rssi_thold; 477 s32 cqm_rssi_thold;
477 u32 cqm_rssi_hyst; 478 u32 cqm_rssi_hyst;
478 u8 subsc_evt_rssi_state; 479 u8 subsc_evt_rssi_state;
480 struct mwifiex_ie mgmt_ie[MAX_MGMT_IE_INDEX];
481 u16 beacon_idx;
482 u16 proberesp_idx;
483 u16 assocresp_idx;
484 u16 rsn_idx;
479}; 485};
480 486
481enum mwifiex_ba_status { 487enum mwifiex_ba_status {
@@ -571,6 +577,7 @@ struct mwifiex_adapter {
571 char fw_name[32]; 577 char fw_name[32];
572 int winner; 578 int winner;
573 struct device *dev; 579 struct device *dev;
580 struct wiphy *wiphy;
574 bool surprise_removed; 581 bool surprise_removed;
575 u32 fw_release_number; 582 u32 fw_release_number;
576 u16 init_wait_q_woken; 583 u16 init_wait_q_woken;
@@ -677,6 +684,8 @@ struct mwifiex_adapter {
677 struct cmd_ctrl_node *cmd_queued; 684 struct cmd_ctrl_node *cmd_queued;
678 spinlock_t queue_lock; /* lock for tx queues */ 685 spinlock_t queue_lock; /* lock for tx queues */
679 struct completion fw_load; 686 struct completion fw_load;
687 u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
688 u16 max_mgmt_ie_index;
680}; 689};
681 690
682int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 691int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -760,6 +769,9 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
760int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, 769int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no,
761 u16 cmd_action, u32 cmd_oid, 770 u16 cmd_action, u32 cmd_oid,
762 void *data_buf, void *cmd_buf); 771 void *data_buf, void *cmd_buf);
772int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
773 u16 cmd_action, u32 cmd_oid,
774 void *data_buf, void *cmd_buf);
763int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, 775int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no,
764 struct host_cmd_ds_command *resp); 776 struct host_cmd_ds_command *resp);
765int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, 777int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *,
@@ -820,6 +832,9 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
820int is_command_pending(struct mwifiex_adapter *adapter); 832int is_command_pending(struct mwifiex_adapter *adapter);
821void mwifiex_init_priv_params(struct mwifiex_private *priv, 833void mwifiex_init_priv_params(struct mwifiex_private *priv,
822 struct net_device *dev); 834 struct net_device *dev);
835int mwifiex_set_secure_params(struct mwifiex_private *priv,
836 struct mwifiex_uap_bss_param *bss_config,
837 struct cfg80211_ap_settings *params);
823 838
824/* 839/*
825 * This function checks if the queuing is RA based or not. 840 * This function checks if the queuing is RA based or not.
@@ -933,7 +948,8 @@ int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
933int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel); 948int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel);
934 949
935int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, 950int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
936 int key_len, u8 key_index, int disable); 951 int key_len, u8 key_index, const u8 *mac_addr,
952 int disable);
937 953
938int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len); 954int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
939 955
@@ -969,6 +985,7 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
969 985
970int mwifiex_main_process(struct mwifiex_adapter *); 986int mwifiex_main_process(struct mwifiex_adapter *);
971 987
988int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel);
972int mwifiex_bss_set_channel(struct mwifiex_private *, 989int mwifiex_bss_set_channel(struct mwifiex_private *,
973 struct mwifiex_chan_freq_power *cfp); 990 struct mwifiex_chan_freq_power *cfp);
974int mwifiex_get_bss_info(struct mwifiex_private *, 991int mwifiex_get_bss_info(struct mwifiex_private *,
@@ -986,6 +1003,11 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
986 u32 *flags, struct vif_params *params); 1003 u32 *flags, struct vif_params *params);
987int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev); 1004int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev);
988 1005
1006void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config);
1007
1008int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
1009 struct cfg80211_ap_settings *params);
1010int mwifiex_del_mgmt_ies(struct mwifiex_private *priv);
989u8 *mwifiex_11d_code_2_region(u8 code); 1011u8 *mwifiex_11d_code_2_region(u8 code);
990 1012
991#ifdef CONFIG_DEBUG_FS 1013#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 87ed2a1f6cd9..40e025da6bc2 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -498,7 +498,8 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
498{ 498{
499 struct host_cmd_ds_802_11_key_material *key_material = 499 struct host_cmd_ds_802_11_key_material *key_material =
500 &cmd->params.key_material; 500 &cmd->params.key_material;
501 u16 key_param_len = 0; 501 struct host_cmd_tlv_mac_addr *tlv_mac;
502 u16 key_param_len = 0, cmd_size;
502 int ret = 0; 503 int ret = 0;
503 const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 504 const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
504 505
@@ -614,11 +615,26 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
614 cpu_to_le16((u16) enc_key->key_len + 615 cpu_to_le16((u16) enc_key->key_len +
615 KEYPARAMSET_FIXED_LEN); 616 KEYPARAMSET_FIXED_LEN);
616 617
617 key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN) 618 key_param_len = (u16)(enc_key->key_len + KEYPARAMSET_FIXED_LEN)
618 + sizeof(struct mwifiex_ie_types_header); 619 + sizeof(struct mwifiex_ie_types_header);
619 620
620 cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN 621 cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN
621 + key_param_len); 622 + key_param_len);
623
624 if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
625 tlv_mac = (void *)((u8 *)&key_material->key_param_set +
626 key_param_len);
627 tlv_mac->tlv.type = cpu_to_le16(TLV_TYPE_STA_MAC_ADDR);
628 tlv_mac->tlv.len = cpu_to_le16(ETH_ALEN);
629 memcpy(tlv_mac->mac_addr, enc_key->mac_addr, ETH_ALEN);
630 cmd_size = key_param_len + S_DS_GEN +
631 sizeof(key_material->action) +
632 sizeof(struct host_cmd_tlv_mac_addr);
633 } else {
634 cmd_size = key_param_len + S_DS_GEN +
635 sizeof(key_material->action);
636 }
637 cmd->size = cpu_to_le16(cmd_size);
622 } 638 }
623 639
624 return ret; 640 return ret;
@@ -1248,13 +1264,15 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1248 if (ret) 1264 if (ret)
1249 return -1; 1265 return -1;
1250 1266
1251 /* Enable IEEE PS by default */ 1267 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
1252 priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; 1268 /* Enable IEEE PS by default */
1253 ret = mwifiex_send_cmd_async(priv, 1269 priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
1254 HostCmd_CMD_802_11_PS_MODE_ENH, 1270 ret = mwifiex_send_cmd_async(
1255 EN_AUTO_PS, BITMAP_STA_PS, NULL); 1271 priv, HostCmd_CMD_802_11_PS_MODE_ENH,
1256 if (ret) 1272 EN_AUTO_PS, BITMAP_STA_PS, NULL);
1257 return -1; 1273 if (ret)
1274 return -1;
1275 }
1258 } 1276 }
1259 1277
1260 /* get tx rate */ 1278 /* get tx rate */
@@ -1270,12 +1288,14 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1270 if (ret) 1288 if (ret)
1271 return -1; 1289 return -1;
1272 1290
1273 /* set ibss coalescing_status */ 1291 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
1274 ret = mwifiex_send_cmd_async(priv, 1292 /* set ibss coalescing_status */
1275 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, 1293 ret = mwifiex_send_cmd_async(
1276 HostCmd_ACT_GEN_SET, 0, &enable); 1294 priv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
1277 if (ret) 1295 HostCmd_ACT_GEN_SET, 0, &enable);
1278 return -1; 1296 if (ret)
1297 return -1;
1298 }
1279 1299
1280 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); 1300 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
1281 amsdu_aggr_ctrl.enable = true; 1301 amsdu_aggr_ctrl.enable = true;
@@ -1293,7 +1313,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1293 if (ret) 1313 if (ret)
1294 return -1; 1314 return -1;
1295 1315
1296 if (first_sta && (priv->adapter->iface_type != MWIFIEX_USB)) { 1316 if (first_sta && priv->adapter->iface_type != MWIFIEX_USB &&
1317 priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
1297 /* Enable auto deep sleep */ 1318 /* Enable auto deep sleep */
1298 auto_ds.auto_ds = DEEP_SLEEP_ON; 1319 auto_ds.auto_ds = DEEP_SLEEP_ON;
1299 auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; 1320 auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
@@ -1305,12 +1326,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1305 return -1; 1326 return -1;
1306 } 1327 }
1307 1328
1308 /* Send cmd to FW to enable/disable 11D function */ 1329 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
1309 state_11d = ENABLE_11D; 1330 /* Send cmd to FW to enable/disable 11D function */
1310 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB, 1331 state_11d = ENABLE_11D;
1311 HostCmd_ACT_GEN_SET, DOT11D_I, &state_11d); 1332 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB,
1312 if (ret) 1333 HostCmd_ACT_GEN_SET, DOT11D_I,
1313 dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); 1334 &state_11d);
1335 if (ret)
1336 dev_err(priv->adapter->dev,
1337 "11D: failed to enable 11D\n");
1338 }
1314 1339
1315 /* Send cmd to FW to configure 11n specific configuration 1340 /* Send cmd to FW to configure 11n specific configuration
1316 * (Short GI, Channel BW, Green field support etc.) for transmit 1341 * (Short GI, Channel BW, Green field support etc.) for transmit
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 3aa54243dea9..a79ed9bd9695 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -944,6 +944,14 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
944 case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: 944 case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
945 ret = mwifiex_ret_subsc_evt(priv, resp, data_buf); 945 ret = mwifiex_ret_subsc_evt(priv, resp, data_buf);
946 break; 946 break;
947 case HostCmd_CMD_UAP_SYS_CONFIG:
948 break;
949 case HostCmd_CMD_UAP_BSS_START:
950 priv->bss_started = 1;
951 break;
952 case HostCmd_CMD_UAP_BSS_STOP:
953 priv->bss_started = 0;
954 break;
947 default: 955 default:
948 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", 956 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
949 resp->command); 957 resp->command);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index f6bbb9307f86..4ace5a3dcd23 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -184,8 +184,10 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
184int mwifiex_process_sta_event(struct mwifiex_private *priv) 184int mwifiex_process_sta_event(struct mwifiex_private *priv)
185{ 185{
186 struct mwifiex_adapter *adapter = priv->adapter; 186 struct mwifiex_adapter *adapter = priv->adapter;
187 int ret = 0; 187 int len, ret = 0;
188 u32 eventcause = adapter->event_cause; 188 u32 eventcause = adapter->event_cause;
189 struct station_info sinfo;
190 struct mwifiex_assoc_event *event;
189 191
190 switch (eventcause) { 192 switch (eventcause) {
191 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: 193 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
@@ -402,6 +404,53 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
402 case EVENT_HOSTWAKE_STAIE: 404 case EVENT_HOSTWAKE_STAIE:
403 dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause); 405 dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause);
404 break; 406 break;
407
408 case EVENT_UAP_STA_ASSOC:
409 skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER);
410 memset(&sinfo, 0, sizeof(sinfo));
411 event = (struct mwifiex_assoc_event *)adapter->event_skb->data;
412 if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) {
413 len = -1;
414
415 if (ieee80211_is_assoc_req(event->frame_control))
416 len = 0;
417 else if (ieee80211_is_reassoc_req(event->frame_control))
418 /* There will be ETH_ALEN bytes of
419 * current_ap_addr before the re-assoc ies.
420 */
421 len = ETH_ALEN;
422
423 if (len != -1) {
424 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
425 sinfo.assoc_req_ies = (u8 *)&event->data[len];
426 len = (u8 *)sinfo.assoc_req_ies -
427 (u8 *)&event->frame_control;
428 sinfo.assoc_req_ies_len =
429 le16_to_cpu(event->len) - (u16)len;
430 }
431 }
432 cfg80211_new_sta(priv->netdev, event->sta_addr, &sinfo,
433 GFP_KERNEL);
434 break;
435 case EVENT_UAP_STA_DEAUTH:
436 skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER);
437 cfg80211_del_sta(priv->netdev, adapter->event_skb->data,
438 GFP_KERNEL);
439 break;
440 case EVENT_UAP_BSS_IDLE:
441 priv->media_connected = false;
442 break;
443 case EVENT_UAP_BSS_ACTIVE:
444 priv->media_connected = true;
445 break;
446 case EVENT_UAP_BSS_START:
447 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause);
448 memcpy(priv->netdev->dev_addr, adapter->event_body+2, ETH_ALEN);
449 break;
450 case EVENT_UAP_MIC_COUNTERMEASURES:
451 /* For future development */
452 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause);
453 break;
405 default: 454 default:
406 dev_dbg(adapter->dev, "event: unknown event id: %#x\n", 455 dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
407 eventcause); 456 eventcause);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 58970e0f7d13..106c449477b2 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -462,7 +462,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
462 462
463 info->bss_chan = bss_desc->channel; 463 info->bss_chan = bss_desc->channel;
464 464
465 memcpy(info->country_code, priv->country_code, 465 memcpy(info->country_code, adapter->country_code,
466 IEEE80211_COUNTRY_STRING_LEN); 466 IEEE80211_COUNTRY_STRING_LEN);
467 467
468 info->media_connected = priv->media_connected; 468 info->media_connected = priv->media_connected;
@@ -1219,7 +1219,8 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version,
1219 * with requisite parameters and calls the IOCTL handler. 1219 * with requisite parameters and calls the IOCTL handler.
1220 */ 1220 */
1221int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, 1221int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
1222 int key_len, u8 key_index, int disable) 1222 int key_len, u8 key_index,
1223 const u8 *mac_addr, int disable)
1223{ 1224{
1224 struct mwifiex_ds_encrypt_key encrypt_key; 1225 struct mwifiex_ds_encrypt_key encrypt_key;
1225 1226
@@ -1229,8 +1230,12 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
1229 encrypt_key.key_index = key_index; 1230 encrypt_key.key_index = key_index;
1230 if (key_len) 1231 if (key_len)
1231 memcpy(encrypt_key.key_material, key, key_len); 1232 memcpy(encrypt_key.key_material, key, key_len);
1233 if (mac_addr)
1234 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
1232 } else { 1235 } else {
1233 encrypt_key.key_disable = true; 1236 encrypt_key.key_disable = true;
1237 if (mac_addr)
1238 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
1234 } 1239 }
1235 1240
1236 return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key); 1241 return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key);
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
new file mode 100644
index 000000000000..76dfbc42a732
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -0,0 +1,432 @@
1/*
2 * Marvell Wireless LAN device driver: AP specific command handling
3 *
4 * Copyright (C) 2012, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "main.h"
21
22/* This function parses security related parameters from cfg80211_ap_settings
23 * and sets into FW understandable bss_config structure.
24 */
25int mwifiex_set_secure_params(struct mwifiex_private *priv,
26 struct mwifiex_uap_bss_param *bss_config,
27 struct cfg80211_ap_settings *params) {
28 int i;
29
30 switch (params->auth_type) {
31 case NL80211_AUTHTYPE_OPEN_SYSTEM:
32 bss_config->auth_mode = WLAN_AUTH_OPEN;
33 break;
34 case NL80211_AUTHTYPE_SHARED_KEY:
35 bss_config->auth_mode = WLAN_AUTH_SHARED_KEY;
36 break;
37 case NL80211_AUTHTYPE_NETWORK_EAP:
38 bss_config->auth_mode = WLAN_AUTH_LEAP;
39 break;
40 default:
41 bss_config->auth_mode = MWIFIEX_AUTH_MODE_AUTO;
42 break;
43 }
44
45 bss_config->key_mgmt_operation |= KEY_MGMT_ON_HOST;
46
47 for (i = 0; i < params->crypto.n_akm_suites; i++) {
48 switch (params->crypto.akm_suites[i]) {
49 case WLAN_AKM_SUITE_8021X:
50 if (params->crypto.wpa_versions &
51 NL80211_WPA_VERSION_1) {
52 bss_config->protocol = PROTOCOL_WPA;
53 bss_config->key_mgmt = KEY_MGMT_EAP;
54 }
55 if (params->crypto.wpa_versions &
56 NL80211_WPA_VERSION_2) {
57 bss_config->protocol = PROTOCOL_WPA2;
58 bss_config->key_mgmt = KEY_MGMT_EAP;
59 }
60 break;
61 case WLAN_AKM_SUITE_PSK:
62 if (params->crypto.wpa_versions &
63 NL80211_WPA_VERSION_1) {
64 bss_config->protocol = PROTOCOL_WPA;
65 bss_config->key_mgmt = KEY_MGMT_PSK;
66 }
67 if (params->crypto.wpa_versions &
68 NL80211_WPA_VERSION_2) {
69 bss_config->protocol = PROTOCOL_WPA2;
70 bss_config->key_mgmt = KEY_MGMT_PSK;
71 }
72 break;
73 default:
74 break;
75 }
76 }
77 for (i = 0; i < params->crypto.n_ciphers_pairwise; i++) {
78 switch (params->crypto.ciphers_pairwise[i]) {
79 case WLAN_CIPHER_SUITE_WEP40:
80 case WLAN_CIPHER_SUITE_WEP104:
81 break;
82 case WLAN_CIPHER_SUITE_TKIP:
83 bss_config->wpa_cfg.pairwise_cipher_wpa = CIPHER_TKIP;
84 break;
85 case WLAN_CIPHER_SUITE_CCMP:
86 bss_config->wpa_cfg.pairwise_cipher_wpa2 =
87 CIPHER_AES_CCMP;
88 default:
89 break;
90 }
91 }
92
93 switch (params->crypto.cipher_group) {
94 case WLAN_CIPHER_SUITE_WEP40:
95 case WLAN_CIPHER_SUITE_WEP104:
96 break;
97 case WLAN_CIPHER_SUITE_TKIP:
98 bss_config->wpa_cfg.group_cipher = CIPHER_TKIP;
99 break;
100 case WLAN_CIPHER_SUITE_CCMP:
101 bss_config->wpa_cfg.group_cipher = CIPHER_AES_CCMP;
102 break;
103 default:
104 break;
105 }
106
107 return 0;
108}
109
110/* This function initializes some of mwifiex_uap_bss_param variables.
111 * This helps FW in ignoring invalid values. These values may or may not
112 * be get updated to valid ones at later stage.
113 */
114void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config)
115{
116 config->bcast_ssid_ctl = 0x7F;
117 config->radio_ctl = 0x7F;
118 config->dtim_period = 0x7F;
119 config->beacon_period = 0x7FFF;
120 config->auth_mode = 0x7F;
121 config->rts_threshold = 0x7FFF;
122 config->frag_threshold = 0x7FFF;
123 config->retry_limit = 0x7F;
124}
125
126/* This function parses BSS related parameters from structure
127 * and prepares TLVs. These TLVs are appended to command buffer.
128*/
129static int
130mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
131{
132 struct host_cmd_tlv_dtim_period *dtim_period;
133 struct host_cmd_tlv_beacon_period *beacon_period;
134 struct host_cmd_tlv_ssid *ssid;
135 struct host_cmd_tlv_channel_band *chan_band;
136 struct host_cmd_tlv_frag_threshold *frag_threshold;
137 struct host_cmd_tlv_rts_threshold *rts_threshold;
138 struct host_cmd_tlv_retry_limit *retry_limit;
139 struct host_cmd_tlv_pwk_cipher *pwk_cipher;
140 struct host_cmd_tlv_gwk_cipher *gwk_cipher;
141 struct host_cmd_tlv_encrypt_protocol *encrypt_protocol;
142 struct host_cmd_tlv_auth_type *auth_type;
143 struct host_cmd_tlv_passphrase *passphrase;
144 struct host_cmd_tlv_akmp *tlv_akmp;
145 struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
146 u16 cmd_size = *param_size;
147
148 if (bss_cfg->ssid.ssid_len) {
149 ssid = (struct host_cmd_tlv_ssid *)tlv;
150 ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_SSID);
151 ssid->tlv.len = cpu_to_le16((u16)bss_cfg->ssid.ssid_len);
152 memcpy(ssid->ssid, bss_cfg->ssid.ssid, bss_cfg->ssid.ssid_len);
153 cmd_size += sizeof(struct host_cmd_tlv) +
154 bss_cfg->ssid.ssid_len;
155 tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len;
156 }
157 if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) {
158 chan_band = (struct host_cmd_tlv_channel_band *)tlv;
159 chan_band->tlv.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
160 chan_band->tlv.len =
161 cpu_to_le16(sizeof(struct host_cmd_tlv_channel_band) -
162 sizeof(struct host_cmd_tlv));
163 chan_band->band_config = bss_cfg->band_cfg;
164 chan_band->channel = bss_cfg->channel;
165 cmd_size += sizeof(struct host_cmd_tlv_channel_band);
166 tlv += sizeof(struct host_cmd_tlv_channel_band);
167 }
168 if (bss_cfg->beacon_period >= MIN_BEACON_PERIOD &&
169 bss_cfg->beacon_period <= MAX_BEACON_PERIOD) {
170 beacon_period = (struct host_cmd_tlv_beacon_period *)tlv;
171 beacon_period->tlv.type =
172 cpu_to_le16(TLV_TYPE_UAP_BEACON_PERIOD);
173 beacon_period->tlv.len =
174 cpu_to_le16(sizeof(struct host_cmd_tlv_beacon_period) -
175 sizeof(struct host_cmd_tlv));
176 beacon_period->period = cpu_to_le16(bss_cfg->beacon_period);
177 cmd_size += sizeof(struct host_cmd_tlv_beacon_period);
178 tlv += sizeof(struct host_cmd_tlv_beacon_period);
179 }
180 if (bss_cfg->dtim_period >= MIN_DTIM_PERIOD &&
181 bss_cfg->dtim_period <= MAX_DTIM_PERIOD) {
182 dtim_period = (struct host_cmd_tlv_dtim_period *)tlv;
183 dtim_period->tlv.type = cpu_to_le16(TLV_TYPE_UAP_DTIM_PERIOD);
184 dtim_period->tlv.len =
185 cpu_to_le16(sizeof(struct host_cmd_tlv_dtim_period) -
186 sizeof(struct host_cmd_tlv));
187 dtim_period->period = bss_cfg->dtim_period;
188 cmd_size += sizeof(struct host_cmd_tlv_dtim_period);
189 tlv += sizeof(struct host_cmd_tlv_dtim_period);
190 }
191 if (bss_cfg->rts_threshold <= MWIFIEX_RTS_MAX_VALUE) {
192 rts_threshold = (struct host_cmd_tlv_rts_threshold *)tlv;
193 rts_threshold->tlv.type =
194 cpu_to_le16(TLV_TYPE_UAP_RTS_THRESHOLD);
195 rts_threshold->tlv.len =
196 cpu_to_le16(sizeof(struct host_cmd_tlv_rts_threshold) -
197 sizeof(struct host_cmd_tlv));
198 rts_threshold->rts_thr = cpu_to_le16(bss_cfg->rts_threshold);
199 cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
200 tlv += sizeof(struct host_cmd_tlv_frag_threshold);
201 }
202 if ((bss_cfg->frag_threshold >= MWIFIEX_FRAG_MIN_VALUE) &&
203 (bss_cfg->frag_threshold <= MWIFIEX_FRAG_MAX_VALUE)) {
204 frag_threshold = (struct host_cmd_tlv_frag_threshold *)tlv;
205 frag_threshold->tlv.type =
206 cpu_to_le16(TLV_TYPE_UAP_FRAG_THRESHOLD);
207 frag_threshold->tlv.len =
208 cpu_to_le16(sizeof(struct host_cmd_tlv_frag_threshold) -
209 sizeof(struct host_cmd_tlv));
210 frag_threshold->frag_thr = cpu_to_le16(bss_cfg->frag_threshold);
211 cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
212 tlv += sizeof(struct host_cmd_tlv_frag_threshold);
213 }
214 if (bss_cfg->retry_limit <= MWIFIEX_RETRY_LIMIT) {
215 retry_limit = (struct host_cmd_tlv_retry_limit *)tlv;
216 retry_limit->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RETRY_LIMIT);
217 retry_limit->tlv.len =
218 cpu_to_le16(sizeof(struct host_cmd_tlv_retry_limit) -
219 sizeof(struct host_cmd_tlv));
220 retry_limit->limit = (u8)bss_cfg->retry_limit;
221 cmd_size += sizeof(struct host_cmd_tlv_retry_limit);
222 tlv += sizeof(struct host_cmd_tlv_retry_limit);
223 }
224 if ((bss_cfg->protocol & PROTOCOL_WPA) ||
225 (bss_cfg->protocol & PROTOCOL_WPA2) ||
226 (bss_cfg->protocol & PROTOCOL_EAP)) {
227 tlv_akmp = (struct host_cmd_tlv_akmp *)tlv;
228 tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP);
229 tlv_akmp->tlv.len =
230 cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) -
231 sizeof(struct host_cmd_tlv));
232 tlv_akmp->key_mgmt_operation =
233 cpu_to_le16(bss_cfg->key_mgmt_operation);
234 tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt);
235 cmd_size += sizeof(struct host_cmd_tlv_akmp);
236 tlv += sizeof(struct host_cmd_tlv_akmp);
237
238 if (bss_cfg->wpa_cfg.pairwise_cipher_wpa &
239 VALID_CIPHER_BITMAP) {
240 pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
241 pwk_cipher->tlv.type =
242 cpu_to_le16(TLV_TYPE_PWK_CIPHER);
243 pwk_cipher->tlv.len = cpu_to_le16(
244 sizeof(struct host_cmd_tlv_pwk_cipher) -
245 sizeof(struct host_cmd_tlv));
246 pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA);
247 pwk_cipher->cipher =
248 bss_cfg->wpa_cfg.pairwise_cipher_wpa;
249 cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
250 tlv += sizeof(struct host_cmd_tlv_pwk_cipher);
251 }
252 if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 &
253 VALID_CIPHER_BITMAP) {
254 pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
255 pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
256 pwk_cipher->tlv.len = cpu_to_le16(
257 sizeof(struct host_cmd_tlv_pwk_cipher) -
258 sizeof(struct host_cmd_tlv));
259 pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2);
260 pwk_cipher->cipher =
261 bss_cfg->wpa_cfg.pairwise_cipher_wpa2;
262 cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
263 tlv += sizeof(struct host_cmd_tlv_pwk_cipher);
264 }
265 if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) {
266 gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv;
267 gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER);
268 gwk_cipher->tlv.len = cpu_to_le16(
269 sizeof(struct host_cmd_tlv_gwk_cipher) -
270 sizeof(struct host_cmd_tlv));
271 gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher;
272 cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher);
273 tlv += sizeof(struct host_cmd_tlv_gwk_cipher);
274 }
275 if (bss_cfg->wpa_cfg.length) {
276 passphrase = (struct host_cmd_tlv_passphrase *)tlv;
277 passphrase->tlv.type =
278 cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE);
279 passphrase->tlv.len =
280 cpu_to_le16(bss_cfg->wpa_cfg.length);
281 memcpy(passphrase->passphrase,
282 bss_cfg->wpa_cfg.passphrase,
283 bss_cfg->wpa_cfg.length);
284 cmd_size += sizeof(struct host_cmd_tlv) +
285 bss_cfg->wpa_cfg.length;
286 tlv += sizeof(struct host_cmd_tlv) +
287 bss_cfg->wpa_cfg.length;
288 }
289 }
290 if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) ||
291 (bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) {
292 auth_type = (struct host_cmd_tlv_auth_type *)tlv;
293 auth_type->tlv.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
294 auth_type->tlv.len =
295 cpu_to_le16(sizeof(struct host_cmd_tlv_auth_type) -
296 sizeof(struct host_cmd_tlv));
297 auth_type->auth_type = (u8)bss_cfg->auth_mode;
298 cmd_size += sizeof(struct host_cmd_tlv_auth_type);
299 tlv += sizeof(struct host_cmd_tlv_auth_type);
300 }
301 if (bss_cfg->protocol) {
302 encrypt_protocol = (struct host_cmd_tlv_encrypt_protocol *)tlv;
303 encrypt_protocol->tlv.type =
304 cpu_to_le16(TLV_TYPE_UAP_ENCRY_PROTOCOL);
305 encrypt_protocol->tlv.len =
306 cpu_to_le16(sizeof(struct host_cmd_tlv_encrypt_protocol)
307 - sizeof(struct host_cmd_tlv));
308 encrypt_protocol->proto = cpu_to_le16(bss_cfg->protocol);
309 cmd_size += sizeof(struct host_cmd_tlv_encrypt_protocol);
310 tlv += sizeof(struct host_cmd_tlv_encrypt_protocol);
311 }
312
313 *param_size = cmd_size;
314
315 return 0;
316}
317
318/* This function parses custom IEs from IE list and prepares command buffer */
319static int mwifiex_uap_custom_ie_prepare(u8 *tlv, void *cmd_buf, u16 *ie_size)
320{
321 struct mwifiex_ie_list *ap_ie = cmd_buf;
322 struct host_cmd_tlv *tlv_ie = (struct host_cmd_tlv *)tlv;
323
324 if (!ap_ie || !ap_ie->len || !ap_ie->ie_list)
325 return -1;
326
327 *ie_size += le16_to_cpu(ap_ie->len) + sizeof(struct host_cmd_tlv);
328
329 tlv_ie->type = cpu_to_le16(TLV_TYPE_MGMT_IE);
330 tlv_ie->len = ap_ie->len;
331 tlv += sizeof(struct host_cmd_tlv);
332
333 memcpy(tlv, ap_ie->ie_list, le16_to_cpu(ap_ie->len));
334
335 return 0;
336}
337
338/* Parse AP config structure and prepare TLV based command structure
339 * to be sent to FW for uAP configuration
340 */
341static int
342mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd, u16 cmd_action,
343 u32 type, void *cmd_buf)
344{
345 u8 *tlv;
346 u16 cmd_size, param_size, ie_size;
347 struct host_cmd_ds_sys_config *sys_cfg;
348
349 cmd->command = cpu_to_le16(HostCmd_CMD_UAP_SYS_CONFIG);
350 cmd_size = (u16)(sizeof(struct host_cmd_ds_sys_config) + S_DS_GEN);
351 sys_cfg = (struct host_cmd_ds_sys_config *)&cmd->params.uap_sys_config;
352 sys_cfg->action = cpu_to_le16(cmd_action);
353 tlv = sys_cfg->tlv;
354
355 switch (type) {
356 case UAP_BSS_PARAMS_I:
357 param_size = cmd_size;
358 if (mwifiex_uap_bss_param_prepare(tlv, cmd_buf, &param_size))
359 return -1;
360 cmd->size = cpu_to_le16(param_size);
361 break;
362 case UAP_CUSTOM_IE_I:
363 ie_size = cmd_size;
364 if (mwifiex_uap_custom_ie_prepare(tlv, cmd_buf, &ie_size))
365 return -1;
366 cmd->size = cpu_to_le16(ie_size);
367 break;
368 default:
369 return -1;
370 }
371
372 return 0;
373}
374
375/* This function prepares the AP specific commands before sending them
376 * to the firmware.
377 * This is a generic function which calls specific command preparation
378 * routines based upon the command number.
379 */
380int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
381 u16 cmd_action, u32 type,
382 void *data_buf, void *cmd_buf)
383{
384 struct host_cmd_ds_command *cmd = cmd_buf;
385
386 switch (cmd_no) {
387 case HostCmd_CMD_UAP_SYS_CONFIG:
388 if (mwifiex_cmd_uap_sys_config(cmd, cmd_action, type, data_buf))
389 return -1;
390 break;
391 case HostCmd_CMD_UAP_BSS_START:
392 case HostCmd_CMD_UAP_BSS_STOP:
393 cmd->command = cpu_to_le16(cmd_no);
394 cmd->size = cpu_to_le16(S_DS_GEN);
395 break;
396 default:
397 dev_err(priv->adapter->dev,
398 "PREP_CMD: unknown cmd %#x\n", cmd_no);
399 return -1;
400 }
401
402 return 0;
403}
404
405/* This function sets the RF channel for AP.
406 *
407 * This function populates channel information in AP config structure
408 * and sends command to configure channel information in AP.
409 */
410int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel)
411{
412 struct mwifiex_uap_bss_param *bss_cfg;
413 struct wiphy *wiphy = priv->wdev->wiphy;
414
415 bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL);
416 if (!bss_cfg)
417 return -ENOMEM;
418
419 bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
420 bss_cfg->channel = channel;
421
422 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG,
423 HostCmd_ACT_GEN_SET,
424 UAP_BSS_PARAMS_I, bss_cfg)) {
425 wiphy_err(wiphy, "Failed to set the uAP channel\n");
426 kfree(bss_cfg);
427 return -1;
428 }
429
430 kfree(bss_cfg);
431 return 0;
432}
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 429a1dee2d26..f3fc65515857 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -885,6 +885,10 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
885 tid_ptr = &(priv_tmp)->wmm. 885 tid_ptr = &(priv_tmp)->wmm.
886 tid_tbl_ptr[tos_to_tid[i]]; 886 tid_tbl_ptr[tos_to_tid[i]];
887 887
888 /* For non-STA ra_list_curr may be NULL */
889 if (!tid_ptr->ra_list_curr)
890 continue;
891
888 spin_lock_irqsave(&tid_ptr->tid_tbl_lock, 892 spin_lock_irqsave(&tid_ptr->tid_tbl_lock,
889 flags); 893 flags);
890 is_list_empty = 894 is_list_empty =
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index b91d1bb30b41..f11953b26024 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -505,9 +505,6 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
505 505
506static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev); 506static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
507 507
508static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev,
509 struct ieee80211_channel *chan, enum nl80211_channel_type channel_type);
510
511static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, 508static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
512 u8 key_index, bool pairwise, const u8 *mac_addr, 509 u8 key_index, bool pairwise, const u8 *mac_addr,
513 struct key_params *params); 510 struct key_params *params);
@@ -549,7 +546,6 @@ static const struct cfg80211_ops rndis_config_ops = {
549 .disconnect = rndis_disconnect, 546 .disconnect = rndis_disconnect,
550 .join_ibss = rndis_join_ibss, 547 .join_ibss = rndis_join_ibss,
551 .leave_ibss = rndis_leave_ibss, 548 .leave_ibss = rndis_leave_ibss,
552 .set_channel = rndis_set_channel,
553 .add_key = rndis_add_key, 549 .add_key = rndis_add_key,
554 .del_key = rndis_del_key, 550 .del_key = rndis_del_key,
555 .set_default_key = rndis_set_default_key, 551 .set_default_key = rndis_set_default_key,
@@ -2398,16 +2394,6 @@ static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
2398 return deauthenticate(usbdev); 2394 return deauthenticate(usbdev);
2399} 2395}
2400 2396
2401static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev,
2402 struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
2403{
2404 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2405 struct usbnet *usbdev = priv->usbdev;
2406
2407 return set_channel(usbdev,
2408 ieee80211_frequency_to_channel(chan->center_freq));
2409}
2410
2411static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, 2397static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
2412 u8 key_index, bool pairwise, const u8 *mac_addr, 2398 u8 key_index, bool pairwise, const u8 *mac_addr,
2413 struct key_params *params) 2399 struct key_params *params)
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 931331d95217..cad25bfebd7a 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -1192,6 +1192,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
1192 { PCI_DEVICE(0x1814, 0x5390) }, 1192 { PCI_DEVICE(0x1814, 0x5390) },
1193 { PCI_DEVICE(0x1814, 0x5392) }, 1193 { PCI_DEVICE(0x1814, 0x5392) },
1194 { PCI_DEVICE(0x1814, 0x539a) }, 1194 { PCI_DEVICE(0x1814, 0x539a) },
1195 { PCI_DEVICE(0x1814, 0x539b) },
1195 { PCI_DEVICE(0x1814, 0x539f) }, 1196 { PCI_DEVICE(0x1814, 0x539f) },
1196#endif 1197#endif
1197 { 0, } 1198 { 0, }
diff --git a/drivers/net/wireless/ti/wl12xx/Kconfig b/drivers/net/wireless/ti/wl12xx/Kconfig
index 5b92329122c4..c2183594655a 100644
--- a/drivers/net/wireless/ti/wl12xx/Kconfig
+++ b/drivers/net/wireless/ti/wl12xx/Kconfig
@@ -1,5 +1,6 @@
1config WL12XX 1config WL12XX
2 tristate "TI wl12xx support" 2 tristate "TI wl12xx support"
3 depends on MAC80211
3 select WLCORE 4 select WLCORE
4 ---help--- 5 ---help---
5 This module adds support for wireless adapters based on TI wl1271, 6 This module adds support for wireless adapters based on TI wl1271,
diff --git a/drivers/net/wireless/ti/wlcore/Kconfig b/drivers/net/wireless/ti/wlcore/Kconfig
index 9d04c38938bc..54156b0b5c2d 100644
--- a/drivers/net/wireless/ti/wlcore/Kconfig
+++ b/drivers/net/wireless/ti/wlcore/Kconfig
@@ -1,6 +1,6 @@
1config WLCORE 1config WLCORE
2 tristate "TI wlcore support" 2 tristate "TI wlcore support"
3 depends on WL_TI && GENERIC_HARDIRQS 3 depends on WL_TI && GENERIC_HARDIRQS && MAC80211
4 depends on INET 4 depends on INET
5 select FW_LOADER 5 select FW_LOADER
6 ---help--- 6 ---help---
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index 5912541a925e..509aa881d790 100644
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -1714,3 +1714,83 @@ out:
1714 return ret; 1714 return ret;
1715 1715
1716} 1716}
1717
1718/* Set the global behaviour of RX filters - On/Off + default action */
1719int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
1720 enum rx_filter_action action)
1721{
1722 struct acx_default_rx_filter *acx;
1723 int ret;
1724
1725 wl1271_debug(DEBUG_ACX, "acx default rx filter en: %d act: %d",
1726 enable, action);
1727
1728 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1729 if (!acx)
1730 return -ENOMEM;
1731
1732 acx->enable = enable;
1733 acx->default_action = action;
1734
1735 ret = wl1271_cmd_configure(wl, ACX_ENABLE_RX_DATA_FILTER, acx,
1736 sizeof(*acx));
1737 if (ret < 0) {
1738 wl1271_warning("acx default rx filter enable failed: %d", ret);
1739 goto out;
1740 }
1741
1742out:
1743 kfree(acx);
1744 return ret;
1745}
1746
1747/* Configure or disable a specific RX filter pattern */
1748int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable,
1749 struct wl12xx_rx_filter *filter)
1750{
1751 struct acx_rx_filter_cfg *acx;
1752 int fields_size = 0;
1753 int acx_size;
1754 int ret;
1755
1756 WARN_ON(enable && !filter);
1757 WARN_ON(index >= WL1271_MAX_RX_FILTERS);
1758
1759 wl1271_debug(DEBUG_ACX,
1760 "acx set rx filter idx: %d enable: %d filter: %p",
1761 index, enable, filter);
1762
1763 if (enable) {
1764 fields_size = wl1271_rx_filter_get_fields_size(filter);
1765
1766 wl1271_debug(DEBUG_ACX, "act: %d num_fields: %d field_size: %d",
1767 filter->action, filter->num_fields, fields_size);
1768 }
1769
1770 acx_size = ALIGN(sizeof(*acx) + fields_size, 4);
1771 acx = kzalloc(acx_size, GFP_KERNEL);
1772
1773 if (!acx)
1774 return -ENOMEM;
1775
1776 acx->enable = enable;
1777 acx->index = index;
1778
1779 if (enable) {
1780 acx->num_fields = filter->num_fields;
1781 acx->action = filter->action;
1782 wl1271_rx_filter_flatten_fields(filter, acx->fields);
1783 }
1784
1785 wl1271_dump(DEBUG_ACX, "RX_FILTER: ", acx, acx_size);
1786
1787 ret = wl1271_cmd_configure(wl, ACX_SET_RX_DATA_FILTER, acx, acx_size);
1788 if (ret < 0) {
1789 wl1271_warning("setting rx filter failed: %d", ret);
1790 goto out;
1791 }
1792
1793out:
1794 kfree(acx);
1795 return ret;
1796}
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
index b2f88831b7a9..8106b2ebfe60 100644
--- a/drivers/net/wireless/ti/wlcore/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -1147,6 +1147,32 @@ struct wl12xx_acx_config_hangover {
1147 u8 padding[2]; 1147 u8 padding[2];
1148} __packed; 1148} __packed;
1149 1149
1150
1151struct acx_default_rx_filter {
1152 struct acx_header header;
1153 u8 enable;
1154
1155 /* action of type FILTER_XXX */
1156 u8 default_action;
1157
1158 u8 pad[2];
1159} __packed;
1160
1161
1162struct acx_rx_filter_cfg {
1163 struct acx_header header;
1164
1165 u8 enable;
1166
1167 /* 0 - WL1271_MAX_RX_FILTERS-1 */
1168 u8 index;
1169
1170 u8 action;
1171
1172 u8 num_fields;
1173 u8 fields[0];
1174} __packed;
1175
1150enum { 1176enum {
1151 ACX_WAKE_UP_CONDITIONS = 0x0000, 1177 ACX_WAKE_UP_CONDITIONS = 0x0000,
1152 ACX_MEM_CFG = 0x0001, 1178 ACX_MEM_CFG = 0x0001,
@@ -1304,5 +1330,9 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
1304int wl1271_acx_fm_coex(struct wl1271 *wl); 1330int wl1271_acx_fm_coex(struct wl1271 *wl);
1305int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl); 1331int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
1306int wl12xx_acx_config_hangover(struct wl1271 *wl); 1332int wl12xx_acx_config_hangover(struct wl1271 *wl);
1333int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
1334 enum rx_filter_action action);
1335int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable,
1336 struct wl12xx_rx_filter *filter);
1307 1337
1308#endif /* __WL1271_ACX_H__ */ 1338#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c
index 3a2207db5405..9b98230f84ce 100644
--- a/drivers/net/wireless/ti/wlcore/boot.c
+++ b/drivers/net/wireless/ti/wlcore/boot.c
@@ -72,7 +72,7 @@ static int wlcore_boot_fw_version(struct wl1271 *wl)
72 struct wl1271_static_data *static_data; 72 struct wl1271_static_data *static_data;
73 int ret; 73 int ret;
74 74
75 static_data = kmalloc(sizeof(*static_data), GFP_DMA); 75 static_data = kmalloc(sizeof(*static_data), GFP_KERNEL | GFP_DMA);
76 if (!static_data) { 76 if (!static_data) {
77 wl1271_error("Couldn't allocate memory for static data!"); 77 wl1271_error("Couldn't allocate memory for static data!");
78 return -ENOMEM; 78 return -ENOMEM;
@@ -413,6 +413,7 @@ int wlcore_boot_run_firmware(struct wl1271 *wl)
413 413
414 /* unmask required mbox events */ 414 /* unmask required mbox events */
415 wl->event_mask = BSS_LOSE_EVENT_ID | 415 wl->event_mask = BSS_LOSE_EVENT_ID |
416 REGAINED_BSS_EVENT_ID |
416 SCAN_COMPLETE_EVENT_ID | 417 SCAN_COMPLETE_EVENT_ID |
417 ROLE_STOP_COMPLETE_EVENT_ID | 418 ROLE_STOP_COMPLETE_EVENT_ID |
418 RSSI_SNR_TRIGGER_0_EVENT_ID | 419 RSSI_SNR_TRIGGER_0_EVENT_ID |
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 5c4716c6f040..5b128a971449 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -123,7 +123,9 @@ static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask)
123 unsigned long timeout; 123 unsigned long timeout;
124 int ret = 0; 124 int ret = 0;
125 125
126 events_vector = kmalloc(sizeof(*events_vector), GFP_DMA); 126 events_vector = kmalloc(sizeof(*events_vector), GFP_KERNEL | GFP_DMA);
127 if (!events_vector)
128 return -ENOMEM;
127 129
128 timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); 130 timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
129 131
@@ -1034,7 +1036,7 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1034 skb_reserve(skb, sizeof(*hdr) + WL1271_EXTRA_SPACE_MAX); 1036 skb_reserve(skb, sizeof(*hdr) + WL1271_EXTRA_SPACE_MAX);
1035 1037
1036 tmpl = (struct wl12xx_arp_rsp_template *)skb_put(skb, sizeof(*tmpl)); 1038 tmpl = (struct wl12xx_arp_rsp_template *)skb_put(skb, sizeof(*tmpl));
1037 memset(tmpl, 0, sizeof(tmpl)); 1039 memset(tmpl, 0, sizeof(*tmpl));
1038 1040
1039 /* llc layer */ 1041 /* llc layer */
1040 memcpy(tmpl->llc_hdr, rfc1042_header, sizeof(rfc1042_header)); 1042 memcpy(tmpl->llc_hdr, rfc1042_header, sizeof(rfc1042_header));
@@ -1083,7 +1085,7 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1083 1085
1084 /* mac80211 header */ 1086 /* mac80211 header */
1085 hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, sizeof(*hdr)); 1087 hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, sizeof(*hdr));
1086 memset(hdr, 0, sizeof(hdr)); 1088 memset(hdr, 0, sizeof(*hdr));
1087 fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS; 1089 fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS;
1088 if (wlvif->sta.qos) 1090 if (wlvif->sta.qos)
1089 fc |= IEEE80211_STYPE_QOS_DATA; 1091 fc |= IEEE80211_STYPE_QOS_DATA;
diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c
index 292632ddf890..28e2a633c3be 100644
--- a/drivers/net/wireless/ti/wlcore/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -103,7 +103,6 @@ static int wl1271_event_process(struct wl1271 *wl)
103 struct ieee80211_vif *vif; 103 struct ieee80211_vif *vif;
104 struct wl12xx_vif *wlvif; 104 struct wl12xx_vif *wlvif;
105 u32 vector; 105 u32 vector;
106 bool beacon_loss = false;
107 bool disconnect_sta = false; 106 bool disconnect_sta = false;
108 unsigned long sta_bitmap = 0; 107 unsigned long sta_bitmap = 0;
109 108
@@ -141,20 +140,23 @@ static int wl1271_event_process(struct wl1271 *wl)
141 mbox->soft_gemini_sense_info); 140 mbox->soft_gemini_sense_info);
142 141
143 /* 142 /*
144 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon 143 * We are HW_MONITOR device. On beacon loss - queue
145 * filtering) is enabled. Without PSM, the stack will receive all 144 * connection loss work. Cancel it on REGAINED event.
146 * beacons and can detect beacon loss by itself.
147 *
148 * As there's possibility that the driver disables PSM before receiving
149 * BSS_LOSE_EVENT, beacon loss has to be reported to the stack.
150 *
151 */ 145 */
152 if (vector & BSS_LOSE_EVENT_ID) { 146 if (vector & BSS_LOSE_EVENT_ID) {
153 /* TODO: check for multi-role */ 147 /* TODO: check for multi-role */
148 int delay = wl->conf.conn.synch_fail_thold *
149 wl->conf.conn.bss_lose_timeout;
154 wl1271_info("Beacon loss detected."); 150 wl1271_info("Beacon loss detected.");
151 cancel_delayed_work_sync(&wl->connection_loss_work);
152 ieee80211_queue_delayed_work(wl->hw, &wl->connection_loss_work,
153 msecs_to_jiffies(delay));
154 }
155 155
156 /* indicate to the stack, that beacons have been lost */ 156 if (vector & REGAINED_BSS_EVENT_ID) {
157 beacon_loss = true; 157 /* TODO: check for multi-role */
158 wl1271_info("Beacon regained.");
159 cancel_delayed_work_sync(&wl->connection_loss_work);
158 } 160 }
159 161
160 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { 162 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
@@ -257,13 +259,6 @@ static int wl1271_event_process(struct wl1271 *wl)
257 rcu_read_unlock(); 259 rcu_read_unlock();
258 } 260 }
259 } 261 }
260
261 if (beacon_loss)
262 wl12xx_for_each_wlvif_sta(wl, wlvif) {
263 vif = wl12xx_wlvif_to_vif(wlvif);
264 ieee80211_connection_loss(vif);
265 }
266
267 return 0; 262 return 0;
268} 263}
269 264
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 2b0f987660c6..acef93390d3d 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -1120,6 +1120,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
1120 cancel_work_sync(&wl->recovery_work); 1120 cancel_work_sync(&wl->recovery_work);
1121 cancel_delayed_work_sync(&wl->elp_work); 1121 cancel_delayed_work_sync(&wl->elp_work);
1122 cancel_delayed_work_sync(&wl->tx_watchdog_work); 1122 cancel_delayed_work_sync(&wl->tx_watchdog_work);
1123 cancel_delayed_work_sync(&wl->connection_loss_work);
1123 1124
1124 mutex_lock(&wl->mutex); 1125 mutex_lock(&wl->mutex);
1125 wl1271_power_off(wl); 1126 wl1271_power_off(wl);
@@ -1261,8 +1262,270 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
1261 1262
1262 1263
1263#ifdef CONFIG_PM 1264#ifdef CONFIG_PM
1265static int
1266wl1271_validate_wowlan_pattern(struct cfg80211_wowlan_trig_pkt_pattern *p)
1267{
1268 int num_fields = 0, in_field = 0, fields_size = 0;
1269 int i, pattern_len = 0;
1270
1271 if (!p->mask) {
1272 wl1271_warning("No mask in WoWLAN pattern");
1273 return -EINVAL;
1274 }
1275
1276 /*
1277 * The pattern is broken up into segments of bytes at different offsets
1278 * that need to be checked by the FW filter. Each segment is called
1279 * a field in the FW API. We verify that the total number of fields
1280 * required for this pattern won't exceed FW limits (8)
1281 * as well as the total fields buffer won't exceed the FW limit.
1282 * Note that if there's a pattern which crosses Ethernet/IP header
1283 * boundary a new field is required.
1284 */
1285 for (i = 0; i < p->pattern_len; i++) {
1286 if (test_bit(i, (unsigned long *)p->mask)) {
1287 if (!in_field) {
1288 in_field = 1;
1289 pattern_len = 1;
1290 } else {
1291 if (i == WL1271_RX_FILTER_ETH_HEADER_SIZE) {
1292 num_fields++;
1293 fields_size += pattern_len +
1294 RX_FILTER_FIELD_OVERHEAD;
1295 pattern_len = 1;
1296 } else
1297 pattern_len++;
1298 }
1299 } else {
1300 if (in_field) {
1301 in_field = 0;
1302 fields_size += pattern_len +
1303 RX_FILTER_FIELD_OVERHEAD;
1304 num_fields++;
1305 }
1306 }
1307 }
1308
1309 if (in_field) {
1310 fields_size += pattern_len + RX_FILTER_FIELD_OVERHEAD;
1311 num_fields++;
1312 }
1313
1314 if (num_fields > WL1271_RX_FILTER_MAX_FIELDS) {
1315 wl1271_warning("RX Filter too complex. Too many segments");
1316 return -EINVAL;
1317 }
1318
1319 if (fields_size > WL1271_RX_FILTER_MAX_FIELDS_SIZE) {
1320 wl1271_warning("RX filter pattern is too big");
1321 return -E2BIG;
1322 }
1323
1324 return 0;
1325}
1326
1327struct wl12xx_rx_filter *wl1271_rx_filter_alloc(void)
1328{
1329 return kzalloc(sizeof(struct wl12xx_rx_filter), GFP_KERNEL);
1330}
1331
1332void wl1271_rx_filter_free(struct wl12xx_rx_filter *filter)
1333{
1334 int i;
1335
1336 if (filter == NULL)
1337 return;
1338
1339 for (i = 0; i < filter->num_fields; i++)
1340 kfree(filter->fields[i].pattern);
1341
1342 kfree(filter);
1343}
1344
1345int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter,
1346 u16 offset, u8 flags,
1347 u8 *pattern, u8 len)
1348{
1349 struct wl12xx_rx_filter_field *field;
1350
1351 if (filter->num_fields == WL1271_RX_FILTER_MAX_FIELDS) {
1352 wl1271_warning("Max fields per RX filter. can't alloc another");
1353 return -EINVAL;
1354 }
1355
1356 field = &filter->fields[filter->num_fields];
1357
1358 field->pattern = kzalloc(len, GFP_KERNEL);
1359 if (!field->pattern) {
1360 wl1271_warning("Failed to allocate RX filter pattern");
1361 return -ENOMEM;
1362 }
1363
1364 filter->num_fields++;
1365
1366 field->offset = cpu_to_le16(offset);
1367 field->flags = flags;
1368 field->len = len;
1369 memcpy(field->pattern, pattern, len);
1370
1371 return 0;
1372}
1373
1374int wl1271_rx_filter_get_fields_size(struct wl12xx_rx_filter *filter)
1375{
1376 int i, fields_size = 0;
1377
1378 for (i = 0; i < filter->num_fields; i++)
1379 fields_size += filter->fields[i].len +
1380 sizeof(struct wl12xx_rx_filter_field) -
1381 sizeof(u8 *);
1382
1383 return fields_size;
1384}
1385
1386void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
1387 u8 *buf)
1388{
1389 int i;
1390 struct wl12xx_rx_filter_field *field;
1391
1392 for (i = 0; i < filter->num_fields; i++) {
1393 field = (struct wl12xx_rx_filter_field *)buf;
1394
1395 field->offset = filter->fields[i].offset;
1396 field->flags = filter->fields[i].flags;
1397 field->len = filter->fields[i].len;
1398
1399 memcpy(&field->pattern, filter->fields[i].pattern, field->len);
1400 buf += sizeof(struct wl12xx_rx_filter_field) -
1401 sizeof(u8 *) + field->len;
1402 }
1403}
1404
1405/*
1406 * Allocates an RX filter returned through f
1407 * which needs to be freed using rx_filter_free()
1408 */
1409static int wl1271_convert_wowlan_pattern_to_rx_filter(
1410 struct cfg80211_wowlan_trig_pkt_pattern *p,
1411 struct wl12xx_rx_filter **f)
1412{
1413 int i, j, ret = 0;
1414 struct wl12xx_rx_filter *filter;
1415 u16 offset;
1416 u8 flags, len;
1417
1418 filter = wl1271_rx_filter_alloc();
1419 if (!filter) {
1420 wl1271_warning("Failed to alloc rx filter");
1421 ret = -ENOMEM;
1422 goto err;
1423 }
1424
1425 i = 0;
1426 while (i < p->pattern_len) {
1427 if (!test_bit(i, (unsigned long *)p->mask)) {
1428 i++;
1429 continue;
1430 }
1431
1432 for (j = i; j < p->pattern_len; j++) {
1433 if (!test_bit(j, (unsigned long *)p->mask))
1434 break;
1435
1436 if (i < WL1271_RX_FILTER_ETH_HEADER_SIZE &&
1437 j >= WL1271_RX_FILTER_ETH_HEADER_SIZE)
1438 break;
1439 }
1440
1441 if (i < WL1271_RX_FILTER_ETH_HEADER_SIZE) {
1442 offset = i;
1443 flags = WL1271_RX_FILTER_FLAG_ETHERNET_HEADER;
1444 } else {
1445 offset = i - WL1271_RX_FILTER_ETH_HEADER_SIZE;
1446 flags = WL1271_RX_FILTER_FLAG_IP_HEADER;
1447 }
1448
1449 len = j - i;
1450
1451 ret = wl1271_rx_filter_alloc_field(filter,
1452 offset,
1453 flags,
1454 &p->pattern[i], len);
1455 if (ret)
1456 goto err;
1457
1458 i = j;
1459 }
1460
1461 filter->action = FILTER_SIGNAL;
1462
1463 *f = filter;
1464 return 0;
1465
1466err:
1467 wl1271_rx_filter_free(filter);
1468 *f = NULL;
1469
1470 return ret;
1471}
1472
1473static int wl1271_configure_wowlan(struct wl1271 *wl,
1474 struct cfg80211_wowlan *wow)
1475{
1476 int i, ret;
1477
1478 if (!wow || wow->any || !wow->n_patterns) {
1479 wl1271_acx_default_rx_filter_enable(wl, 0, FILTER_SIGNAL);
1480 wl1271_rx_filter_clear_all(wl);
1481 return 0;
1482 }
1483
1484 if (WARN_ON(wow->n_patterns > WL1271_MAX_RX_FILTERS))
1485 return -EINVAL;
1486
1487 /* Validate all incoming patterns before clearing current FW state */
1488 for (i = 0; i < wow->n_patterns; i++) {
1489 ret = wl1271_validate_wowlan_pattern(&wow->patterns[i]);
1490 if (ret) {
1491 wl1271_warning("Bad wowlan pattern %d", i);
1492 return ret;
1493 }
1494 }
1495
1496 wl1271_acx_default_rx_filter_enable(wl, 0, FILTER_SIGNAL);
1497 wl1271_rx_filter_clear_all(wl);
1498
1499 /* Translate WoWLAN patterns into filters */
1500 for (i = 0; i < wow->n_patterns; i++) {
1501 struct cfg80211_wowlan_trig_pkt_pattern *p;
1502 struct wl12xx_rx_filter *filter = NULL;
1503
1504 p = &wow->patterns[i];
1505
1506 ret = wl1271_convert_wowlan_pattern_to_rx_filter(p, &filter);
1507 if (ret) {
1508 wl1271_warning("Failed to create an RX filter from "
1509 "wowlan pattern %d", i);
1510 goto out;
1511 }
1512
1513 ret = wl1271_rx_filter_enable(wl, i, 1, filter);
1514
1515 wl1271_rx_filter_free(filter);
1516 if (ret)
1517 goto out;
1518 }
1519
1520 ret = wl1271_acx_default_rx_filter_enable(wl, 1, FILTER_DROP);
1521
1522out:
1523 return ret;
1524}
1525
1264static int wl1271_configure_suspend_sta(struct wl1271 *wl, 1526static int wl1271_configure_suspend_sta(struct wl1271 *wl,
1265 struct wl12xx_vif *wlvif) 1527 struct wl12xx_vif *wlvif,
1528 struct cfg80211_wowlan *wow)
1266{ 1529{
1267 int ret = 0; 1530 int ret = 0;
1268 1531
@@ -1273,6 +1536,7 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
1273 if (ret < 0) 1536 if (ret < 0)
1274 goto out; 1537 goto out;
1275 1538
1539 wl1271_configure_wowlan(wl, wow);
1276 ret = wl1271_acx_wake_up_conditions(wl, wlvif, 1540 ret = wl1271_acx_wake_up_conditions(wl, wlvif,
1277 wl->conf.conn.suspend_wake_up_event, 1541 wl->conf.conn.suspend_wake_up_event,
1278 wl->conf.conn.suspend_listen_interval); 1542 wl->conf.conn.suspend_listen_interval);
@@ -1308,10 +1572,11 @@ out:
1308} 1572}
1309 1573
1310static int wl1271_configure_suspend(struct wl1271 *wl, 1574static int wl1271_configure_suspend(struct wl1271 *wl,
1311 struct wl12xx_vif *wlvif) 1575 struct wl12xx_vif *wlvif,
1576 struct cfg80211_wowlan *wow)
1312{ 1577{
1313 if (wlvif->bss_type == BSS_TYPE_STA_BSS) 1578 if (wlvif->bss_type == BSS_TYPE_STA_BSS)
1314 return wl1271_configure_suspend_sta(wl, wlvif); 1579 return wl1271_configure_suspend_sta(wl, wlvif, wow);
1315 if (wlvif->bss_type == BSS_TYPE_AP_BSS) 1580 if (wlvif->bss_type == BSS_TYPE_AP_BSS)
1316 return wl1271_configure_suspend_ap(wl, wlvif); 1581 return wl1271_configure_suspend_ap(wl, wlvif);
1317 return 0; 1582 return 0;
@@ -1332,6 +1597,8 @@ static void wl1271_configure_resume(struct wl1271 *wl,
1332 return; 1597 return;
1333 1598
1334 if (is_sta) { 1599 if (is_sta) {
1600 wl1271_configure_wowlan(wl, NULL);
1601
1335 ret = wl1271_acx_wake_up_conditions(wl, wlvif, 1602 ret = wl1271_acx_wake_up_conditions(wl, wlvif,
1336 wl->conf.conn.wake_up_event, 1603 wl->conf.conn.wake_up_event,
1337 wl->conf.conn.listen_interval); 1604 wl->conf.conn.listen_interval);
@@ -1355,15 +1622,16 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1355 int ret; 1622 int ret;
1356 1623
1357 wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); 1624 wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
1358 WARN_ON(!wow || !wow->any); 1625 WARN_ON(!wow);
1359 1626
1360 wl1271_tx_flush(wl); 1627 wl1271_tx_flush(wl);
1361 1628
1362 mutex_lock(&wl->mutex); 1629 mutex_lock(&wl->mutex);
1363 wl->wow_enabled = true; 1630 wl->wow_enabled = true;
1364 wl12xx_for_each_wlvif(wl, wlvif) { 1631 wl12xx_for_each_wlvif(wl, wlvif) {
1365 ret = wl1271_configure_suspend(wl, wlvif); 1632 ret = wl1271_configure_suspend(wl, wlvif, wow);
1366 if (ret < 0) { 1633 if (ret < 0) {
1634 mutex_unlock(&wl->mutex);
1367 wl1271_warning("couldn't prepare device to suspend"); 1635 wl1271_warning("couldn't prepare device to suspend");
1368 return ret; 1636 return ret;
1369 } 1637 }
@@ -1487,6 +1755,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1487 cancel_work_sync(&wl->tx_work); 1755 cancel_work_sync(&wl->tx_work);
1488 cancel_delayed_work_sync(&wl->elp_work); 1756 cancel_delayed_work_sync(&wl->elp_work);
1489 cancel_delayed_work_sync(&wl->tx_watchdog_work); 1757 cancel_delayed_work_sync(&wl->tx_watchdog_work);
1758 cancel_delayed_work_sync(&wl->connection_loss_work);
1490 1759
1491 /* let's notify MAC80211 about the remaining pending TX frames */ 1760 /* let's notify MAC80211 about the remaining pending TX frames */
1492 wl12xx_tx_reset(wl, true); 1761 wl12xx_tx_reset(wl, true);
@@ -3439,6 +3708,9 @@ sta_not_found:
3439 do_join = true; 3708 do_join = true;
3440 set_assoc = true; 3709 set_assoc = true;
3441 3710
3711 /* Cancel connection_loss_work */
3712 cancel_delayed_work_sync(&wl->connection_loss_work);
3713
3442 /* 3714 /*
3443 * use basic rates from AP, and determine lowest rate 3715 * use basic rates from AP, and determine lowest rate
3444 * to use with control frames. 3716 * to use with control frames.
@@ -4549,6 +4821,34 @@ static struct bin_attribute fwlog_attr = {
4549 .read = wl1271_sysfs_read_fwlog, 4821 .read = wl1271_sysfs_read_fwlog,
4550}; 4822};
4551 4823
4824static void wl1271_connection_loss_work(struct work_struct *work)
4825{
4826 struct delayed_work *dwork;
4827 struct wl1271 *wl;
4828 struct ieee80211_vif *vif;
4829 struct wl12xx_vif *wlvif;
4830
4831 dwork = container_of(work, struct delayed_work, work);
4832 wl = container_of(dwork, struct wl1271, connection_loss_work);
4833
4834 wl1271_info("Connection loss work.");
4835
4836 mutex_lock(&wl->mutex);
4837
4838 if (unlikely(wl->state == WL1271_STATE_OFF))
4839 goto out;
4840
4841 /* Call mac80211 connection loss */
4842 wl12xx_for_each_wlvif_sta(wl, wlvif) {
4843 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
4844 goto out;
4845 vif = wl12xx_wlvif_to_vif(wlvif);
4846 ieee80211_connection_loss(vif);
4847 }
4848out:
4849 mutex_unlock(&wl->mutex);
4850}
4851
4552static void wl12xx_derive_mac_addresses(struct wl1271 *wl, 4852static void wl12xx_derive_mac_addresses(struct wl1271 *wl,
4553 u32 oui, u32 nic, int n) 4853 u32 oui, u32 nic, int n)
4554{ 4854{
@@ -4804,6 +5104,8 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size)
4804 INIT_WORK(&wl->recovery_work, wl1271_recovery_work); 5104 INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
4805 INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); 5105 INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
4806 INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work); 5106 INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work);
5107 INIT_DELAYED_WORK(&wl->connection_loss_work,
5108 wl1271_connection_loss_work);
4807 5109
4808 wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); 5110 wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
4809 if (!wl->freezable_wq) { 5111 if (!wl->freezable_wq) {
@@ -4861,7 +5163,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size)
4861 goto err_dummy_packet; 5163 goto err_dummy_packet;
4862 } 5164 }
4863 5165
4864 wl->mbox = kmalloc(sizeof(*wl->mbox), GFP_DMA); 5166 wl->mbox = kmalloc(sizeof(*wl->mbox), GFP_KERNEL | GFP_DMA);
4865 if (!wl->mbox) { 5167 if (!wl->mbox) {
4866 ret = -ENOMEM; 5168 ret = -ENOMEM;
4867 goto err_fwlog; 5169 goto err_fwlog;
@@ -5003,9 +5305,14 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
5003 if (!ret) { 5305 if (!ret) {
5004 wl->irq_wake_enabled = true; 5306 wl->irq_wake_enabled = true;
5005 device_init_wakeup(wl->dev, 1); 5307 device_init_wakeup(wl->dev, 1);
5006 if (pdata->pwr_in_suspend) 5308 if (pdata->pwr_in_suspend) {
5007 wl->hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY; 5309 wl->hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
5008 5310 wl->hw->wiphy->wowlan.n_patterns =
5311 WL1271_MAX_RX_FILTERS;
5312 wl->hw->wiphy->wowlan.pattern_min_len = 1;
5313 wl->hw->wiphy->wowlan.pattern_max_len =
5314 WL1271_RX_FILTER_MAX_PATTERN_SIZE;
5315 }
5009 } 5316 }
5010 disable_irq(wl->irq); 5317 disable_irq(wl->irq);
5011 5318
diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c
index 89bd9385e90b..1f1d9488dfb6 100644
--- a/drivers/net/wireless/ti/wlcore/rx.c
+++ b/drivers/net/wireless/ti/wlcore/rx.c
@@ -278,3 +278,39 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status)
278 278
279 wl12xx_rearm_rx_streaming(wl, active_hlids); 279 wl12xx_rearm_rx_streaming(wl, active_hlids);
280} 280}
281
282int wl1271_rx_filter_enable(struct wl1271 *wl,
283 int index, bool enable,
284 struct wl12xx_rx_filter *filter)
285{
286 int ret;
287
288 if (wl->rx_filter_enabled[index] == enable) {
289 wl1271_warning("Request to enable an already "
290 "enabled rx filter %d", index);
291 return 0;
292 }
293
294 ret = wl1271_acx_set_rx_filter(wl, index, enable, filter);
295
296 if (ret) {
297 wl1271_error("Failed to %s rx data filter %d (err=%d)",
298 enable ? "enable" : "disable", index, ret);
299 return ret;
300 }
301
302 wl->rx_filter_enabled[index] = enable;
303
304 return 0;
305}
306
307void wl1271_rx_filter_clear_all(struct wl1271 *wl)
308{
309 int i;
310
311 for (i = 0; i < WL1271_MAX_RX_FILTERS; i++) {
312 if (!wl->rx_filter_enabled[i])
313 continue;
314 wl1271_rx_filter_enable(wl, i, 0, NULL);
315 }
316}
diff --git a/drivers/net/wireless/ti/wlcore/rx.h b/drivers/net/wireless/ti/wlcore/rx.h
index 6e129e2a8546..e9a162a864ca 100644
--- a/drivers/net/wireless/ti/wlcore/rx.h
+++ b/drivers/net/wireless/ti/wlcore/rx.h
@@ -138,5 +138,9 @@ struct wl1271_rx_descriptor {
138 138
139void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status); 139void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status);
140u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); 140u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
141int wl1271_rx_filter_enable(struct wl1271 *wl,
142 int index, bool enable,
143 struct wl12xx_rx_filter *filter);
144void wl1271_rx_filter_clear_all(struct wl1271 *wl);
141 145
142#endif 146#endif
diff --git a/drivers/net/wireless/ti/wlcore/wl12xx.h b/drivers/net/wireless/ti/wlcore/wl12xx.h
index a9b220c43e54..f12bdf745180 100644
--- a/drivers/net/wireless/ti/wlcore/wl12xx.h
+++ b/drivers/net/wireless/ti/wlcore/wl12xx.h
@@ -279,6 +279,39 @@ struct wl1271_link {
279 u8 ba_bitmap; 279 u8 ba_bitmap;
280}; 280};
281 281
282#define WL1271_MAX_RX_FILTERS 5
283#define WL1271_RX_FILTER_MAX_FIELDS 8
284
285#define WL1271_RX_FILTER_ETH_HEADER_SIZE 14
286#define WL1271_RX_FILTER_MAX_FIELDS_SIZE 95
287#define RX_FILTER_FIELD_OVERHEAD \
288 (sizeof(struct wl12xx_rx_filter_field) - sizeof(u8 *))
289#define WL1271_RX_FILTER_MAX_PATTERN_SIZE \
290 (WL1271_RX_FILTER_MAX_FIELDS_SIZE - RX_FILTER_FIELD_OVERHEAD)
291
292#define WL1271_RX_FILTER_FLAG_MASK BIT(0)
293#define WL1271_RX_FILTER_FLAG_IP_HEADER 0
294#define WL1271_RX_FILTER_FLAG_ETHERNET_HEADER BIT(1)
295
296enum rx_filter_action {
297 FILTER_DROP = 0,
298 FILTER_SIGNAL = 1,
299 FILTER_FW_HANDLE = 2
300};
301
302struct wl12xx_rx_filter_field {
303 __le16 offset;
304 u8 len;
305 u8 flags;
306 u8 *pattern;
307} __packed;
308
309struct wl12xx_rx_filter {
310 u8 action;
311 int num_fields;
312 struct wl12xx_rx_filter_field fields[WL1271_RX_FILTER_MAX_FIELDS];
313};
314
282struct wl1271_station { 315struct wl1271_station {
283 u8 hlid; 316 u8 hlid;
284}; 317};
@@ -439,6 +472,14 @@ int wl1271_plt_stop(struct wl1271 *wl);
439int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif); 472int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif);
440void wl12xx_queue_recovery_work(struct wl1271 *wl); 473void wl12xx_queue_recovery_work(struct wl1271 *wl);
441size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen); 474size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen);
475int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter,
476 u16 offset, u8 flags,
477 u8 *pattern, u8 len);
478void wl1271_rx_filter_free(struct wl12xx_rx_filter *filter);
479struct wl12xx_rx_filter *wl1271_rx_filter_alloc(void);
480int wl1271_rx_filter_get_fields_size(struct wl12xx_rx_filter *filter);
481void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
482 u8 *buf);
442 483
443#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */ 484#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
444 485
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 39f9fadfebd9..0b3f0b586f4b 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -243,6 +243,9 @@ struct wl1271 {
243 struct wl1271_scan scan; 243 struct wl1271_scan scan;
244 struct delayed_work scan_complete_work; 244 struct delayed_work scan_complete_work;
245 245
246 /* Connection loss work */
247 struct delayed_work connection_loss_work;
248
246 bool sched_scanning; 249 bool sched_scanning;
247 250
248 /* The current band */ 251 /* The current band */
@@ -349,6 +352,9 @@ struct wl1271 {
349 352
350 /* size of the private FW status data */ 353 /* size of the private FW status data */
351 size_t fw_status_priv_len; 354 size_t fw_status_priv_len;
355
356 /* RX Data filter rule state - enabled/disabled */
357 bool rx_filter_enabled[WL1271_MAX_RX_FILTERS];
352}; 358};
353 359
354int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); 360int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
index 5af959274d4e..3b20b73ee649 100644
--- a/drivers/nfc/Kconfig
+++ b/drivers/nfc/Kconfig
@@ -17,6 +17,19 @@ config PN544_NFC
17 To compile this driver as a module, choose m here. The module will 17 To compile this driver as a module, choose m here. The module will
18 be called pn544. 18 be called pn544.
19 19
20config PN544_HCI_NFC
21 tristate "HCI PN544 NFC driver"
22 depends on I2C && NFC_SHDLC
23 select CRC_CCITT
24 default n
25 ---help---
26 NXP PN544 i2c driver.
27 This is a driver based on the SHDLC and HCI NFC kernel layers and
28 will thus not work with NXP libnfc library.
29
30 To compile this driver as a module, choose m here. The module will
31 be called pn544_hci.
32
20config NFC_PN533 33config NFC_PN533
21 tristate "NXP PN533 USB driver" 34 tristate "NXP PN533 USB driver"
22 depends on USB 35 depends on USB
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile
index ab99e8572f02..473e44cef612 100644
--- a/drivers/nfc/Makefile
+++ b/drivers/nfc/Makefile
@@ -3,6 +3,7 @@
3# 3#
4 4
5obj-$(CONFIG_PN544_NFC) += pn544.o 5obj-$(CONFIG_PN544_NFC) += pn544.o
6obj-$(CONFIG_PN544_HCI_NFC) += pn544_hci.o
6obj-$(CONFIG_NFC_PN533) += pn533.o 7obj-$(CONFIG_NFC_PN533) += pn533.o
7obj-$(CONFIG_NFC_WILINK) += nfcwilink.o 8obj-$(CONFIG_NFC_WILINK) += nfcwilink.o
8 9
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c
index e6ec16d92e65..19110f0eb15f 100644
--- a/drivers/nfc/pn533.c
+++ b/drivers/nfc/pn533.c
@@ -394,9 +394,6 @@ static void pn533_wq_cmd_complete(struct work_struct *work)
394 struct pn533_frame *in_frame; 394 struct pn533_frame *in_frame;
395 int rc; 395 int rc;
396 396
397 if (dev == NULL)
398 return;
399
400 in_frame = dev->wq_in_frame; 397 in_frame = dev->wq_in_frame;
401 398
402 if (dev->wq_in_error) 399 if (dev->wq_in_error)
@@ -1194,8 +1191,8 @@ static int pn533_activate_target_nfcdep(struct pn533 *dev)
1194 return rc; 1191 return rc;
1195} 1192}
1196 1193
1197static int pn533_activate_target(struct nfc_dev *nfc_dev, u32 target_idx, 1194static int pn533_activate_target(struct nfc_dev *nfc_dev,
1198 u32 protocol) 1195 struct nfc_target *target, u32 protocol)
1199{ 1196{
1200 struct pn533 *dev = nfc_get_drvdata(nfc_dev); 1197 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1201 int rc; 1198 int rc;
@@ -1243,7 +1240,8 @@ static int pn533_activate_target(struct nfc_dev *nfc_dev, u32 target_idx,
1243 return 0; 1240 return 0;
1244} 1241}
1245 1242
1246static void pn533_deactivate_target(struct nfc_dev *nfc_dev, u32 target_idx) 1243static void pn533_deactivate_target(struct nfc_dev *nfc_dev,
1244 struct nfc_target *target)
1247{ 1245{
1248 struct pn533 *dev = nfc_get_drvdata(nfc_dev); 1246 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1249 u8 tg; 1247 u8 tg;
@@ -1351,7 +1349,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
1351 return 0; 1349 return 0;
1352} 1350}
1353 1351
1354static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, 1352static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
1355 u8 comm_mode, u8* gb, size_t gb_len) 1353 u8 comm_mode, u8* gb, size_t gb_len)
1356{ 1354{
1357 struct pn533 *dev = nfc_get_drvdata(nfc_dev); 1355 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
@@ -1552,10 +1550,9 @@ error:
1552 return 0; 1550 return 0;
1553} 1551}
1554 1552
1555static int pn533_data_exchange(struct nfc_dev *nfc_dev, u32 target_idx, 1553static int pn533_data_exchange(struct nfc_dev *nfc_dev,
1556 struct sk_buff *skb, 1554 struct nfc_target *target, struct sk_buff *skb,
1557 data_exchange_cb_t cb, 1555 data_exchange_cb_t cb, void *cb_context)
1558 void *cb_context)
1559{ 1556{
1560 struct pn533 *dev = nfc_get_drvdata(nfc_dev); 1557 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1561 struct pn533_frame *out_frame, *in_frame; 1558 struct pn533_frame *out_frame, *in_frame;
diff --git a/drivers/nfc/pn544_hci.c b/drivers/nfc/pn544_hci.c
new file mode 100644
index 000000000000..46f4a9f9f5e4
--- /dev/null
+++ b/drivers/nfc/pn544_hci.c
@@ -0,0 +1,947 @@
1/*
2 * HCI based Driver for NXP PN544 NFC Chip
3 *
4 * Copyright (C) 2012 Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the
17 * Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/crc-ccitt.h>
22#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/slab.h>
25#include <linux/miscdevice.h>
26#include <linux/interrupt.h>
27#include <linux/gpio.h>
28#include <linux/i2c.h>
29
30#include <linux/nfc.h>
31#include <net/nfc/hci.h>
32#include <net/nfc/shdlc.h>
33
34#include <linux/nfc/pn544.h>
35
36#define DRIVER_DESC "HCI NFC driver for PN544"
37
38#define PN544_HCI_DRIVER_NAME "pn544_hci"
39
40/* Timing restrictions (ms) */
41#define PN544_HCI_RESETVEN_TIME 30
42
43static struct i2c_device_id pn544_hci_id_table[] = {
44 {"pn544", 0},
45 {}
46};
47
48MODULE_DEVICE_TABLE(i2c, pn544_hci_id_table);
49
50#define HCI_MODE 0
51#define FW_MODE 1
52
53/* framing in HCI mode */
54#define PN544_HCI_LLC_LEN 1
55#define PN544_HCI_LLC_CRC 2
56#define PN544_HCI_LLC_LEN_CRC (PN544_HCI_LLC_LEN + PN544_HCI_LLC_CRC)
57#define PN544_HCI_LLC_MIN_SIZE (1 + PN544_HCI_LLC_LEN_CRC)
58#define PN544_HCI_LLC_MAX_PAYLOAD 29
59#define PN544_HCI_LLC_MAX_SIZE (PN544_HCI_LLC_LEN_CRC + 1 + \
60 PN544_HCI_LLC_MAX_PAYLOAD)
61
62enum pn544_state {
63 PN544_ST_COLD,
64 PN544_ST_FW_READY,
65 PN544_ST_READY,
66};
67
68#define FULL_VERSION_LEN 11
69
70/* Proprietary commands */
71#define PN544_WRITE 0x3f
72
73/* Proprietary gates, events, commands and registers */
74
75/* NFC_HCI_RF_READER_A_GATE additional registers and commands */
76#define PN544_RF_READER_A_AUTO_ACTIVATION 0x10
77#define PN544_RF_READER_A_CMD_CONTINUE_ACTIVATION 0x12
78#define PN544_MIFARE_CMD 0x21
79
80/* Commands that apply to all RF readers */
81#define PN544_RF_READER_CMD_PRESENCE_CHECK 0x30
82#define PN544_RF_READER_CMD_ACTIVATE_NEXT 0x32
83
84/* NFC_HCI_ID_MGMT_GATE additional registers */
85#define PN544_ID_MGMT_FULL_VERSION_SW 0x10
86
87#define PN544_RF_READER_ISO15693_GATE 0x12
88
89#define PN544_RF_READER_F_GATE 0x14
90#define PN544_FELICA_ID 0x04
91#define PN544_FELICA_RAW 0x20
92
93#define PN544_RF_READER_JEWEL_GATE 0x15
94#define PN544_JEWEL_RAW_CMD 0x23
95
96#define PN544_RF_READER_NFCIP1_INITIATOR_GATE 0x30
97#define PN544_RF_READER_NFCIP1_TARGET_GATE 0x31
98
99#define PN544_SYS_MGMT_GATE 0x90
100#define PN544_SYS_MGMT_INFO_NOTIFICATION 0x02
101
102#define PN544_POLLING_LOOP_MGMT_GATE 0x94
103#define PN544_PL_RDPHASES 0x06
104#define PN544_PL_EMULATION 0x07
105#define PN544_PL_NFCT_DEACTIVATED 0x09
106
107#define PN544_SWP_MGMT_GATE 0xA0
108
109#define PN544_NFC_WI_MGMT_GATE 0xA1
110
111static u8 pn544_custom_gates[] = {
112 PN544_SYS_MGMT_GATE,
113 PN544_SWP_MGMT_GATE,
114 PN544_POLLING_LOOP_MGMT_GATE,
115 PN544_NFC_WI_MGMT_GATE,
116 PN544_RF_READER_F_GATE,
117 PN544_RF_READER_JEWEL_GATE,
118 PN544_RF_READER_ISO15693_GATE,
119 PN544_RF_READER_NFCIP1_INITIATOR_GATE,
120 PN544_RF_READER_NFCIP1_TARGET_GATE
121};
122
123/* Largest headroom needed for outgoing custom commands */
124#define PN544_CMDS_HEADROOM 2
125
126struct pn544_hci_info {
127 struct i2c_client *i2c_dev;
128 struct nfc_shdlc *shdlc;
129
130 enum pn544_state state;
131
132 struct mutex info_lock;
133
134 unsigned int gpio_en;
135 unsigned int gpio_irq;
136 unsigned int gpio_fw;
137 unsigned int en_polarity;
138
139 int hard_fault; /*
140 * < 0 if hardware error occured (e.g. i2c err)
141 * and prevents normal operation.
142 */
143};
144
145static void pn544_hci_platform_init(struct pn544_hci_info *info)
146{
147 int polarity, retry, ret;
148 char rset_cmd[] = { 0x05, 0xF9, 0x04, 0x00, 0xC3, 0xE5 };
149 int count = sizeof(rset_cmd);
150
151 pr_info(DRIVER_DESC ": %s\n", __func__);
152 dev_info(&info->i2c_dev->dev, "Detecting nfc_en polarity\n");
153
154 /* Disable fw download */
155 gpio_set_value(info->gpio_fw, 0);
156
157 for (polarity = 0; polarity < 2; polarity++) {
158 info->en_polarity = polarity;
159 retry = 3;
160 while (retry--) {
161 /* power off */
162 gpio_set_value(info->gpio_en, !info->en_polarity);
163 usleep_range(10000, 15000);
164
165 /* power on */
166 gpio_set_value(info->gpio_en, info->en_polarity);
167 usleep_range(10000, 15000);
168
169 /* send reset */
170 dev_dbg(&info->i2c_dev->dev, "Sending reset cmd\n");
171 ret = i2c_master_send(info->i2c_dev, rset_cmd, count);
172 if (ret == count) {
173 dev_info(&info->i2c_dev->dev,
174 "nfc_en polarity : active %s\n",
175 (polarity == 0 ? "low" : "high"));
176 goto out;
177 }
178 }
179 }
180
181 dev_err(&info->i2c_dev->dev,
182 "Could not detect nfc_en polarity, fallback to active high\n");
183
184out:
185 gpio_set_value(info->gpio_en, !info->en_polarity);
186}
187
188static int pn544_hci_enable(struct pn544_hci_info *info, int mode)
189{
190 pr_info(DRIVER_DESC ": %s\n", __func__);
191
192 gpio_set_value(info->gpio_fw, 0);
193 gpio_set_value(info->gpio_en, info->en_polarity);
194 usleep_range(10000, 15000);
195
196 return 0;
197}
198
199static void pn544_hci_disable(struct pn544_hci_info *info)
200{
201 pr_info(DRIVER_DESC ": %s\n", __func__);
202
203 gpio_set_value(info->gpio_fw, 0);
204 gpio_set_value(info->gpio_en, !info->en_polarity);
205 usleep_range(10000, 15000);
206
207 gpio_set_value(info->gpio_en, info->en_polarity);
208 usleep_range(10000, 15000);
209
210 gpio_set_value(info->gpio_en, !info->en_polarity);
211 usleep_range(10000, 15000);
212}
213
214static int pn544_hci_i2c_write(struct i2c_client *client, u8 *buf, int len)
215{
216 int r;
217
218 usleep_range(3000, 6000);
219
220 r = i2c_master_send(client, buf, len);
221
222 if (r == -EREMOTEIO) { /* Retry, chip was in standby */
223 usleep_range(6000, 10000);
224 r = i2c_master_send(client, buf, len);
225 }
226
227 if (r >= 0 && r != len)
228 r = -EREMOTEIO;
229
230 return r;
231}
232
233static int check_crc(u8 *buf, int buflen)
234{
235 u8 len;
236 u16 crc;
237
238 len = buf[0] + 1;
239 crc = crc_ccitt(0xffff, buf, len - 2);
240 crc = ~crc;
241
242 if (buf[len - 2] != (crc & 0xff) || buf[len - 1] != (crc >> 8)) {
243 pr_err(PN544_HCI_DRIVER_NAME ": CRC error 0x%x != 0x%x 0x%x\n",
244 crc, buf[len - 1], buf[len - 2]);
245
246 pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__);
247 print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE,
248 16, 2, buf, buflen, false);
249 return -EPERM;
250 }
251 return 0;
252}
253
254/*
255 * Reads an shdlc frame and returns it in a newly allocated sk_buff. Guarantees
256 * that i2c bus will be flushed and that next read will start on a new frame.
257 * returned skb contains only LLC header and payload.
258 * returns:
259 * -EREMOTEIO : i2c read error (fatal)
260 * -EBADMSG : frame was incorrect and discarded
261 * -ENOMEM : cannot allocate skb, frame dropped
262 */
263static int pn544_hci_i2c_read(struct i2c_client *client, struct sk_buff **skb)
264{
265 int r;
266 u8 len;
267 u8 tmp[PN544_HCI_LLC_MAX_SIZE - 1];
268
269 r = i2c_master_recv(client, &len, 1);
270 if (r != 1) {
271 dev_err(&client->dev, "cannot read len byte\n");
272 return -EREMOTEIO;
273 }
274
275 if ((len < (PN544_HCI_LLC_MIN_SIZE - 1)) ||
276 (len > (PN544_HCI_LLC_MAX_SIZE - 1))) {
277 dev_err(&client->dev, "invalid len byte\n");
278 r = -EBADMSG;
279 goto flush;
280 }
281
282 *skb = alloc_skb(1 + len, GFP_KERNEL);
283 if (*skb == NULL) {
284 r = -ENOMEM;
285 goto flush;
286 }
287
288 *skb_put(*skb, 1) = len;
289
290 r = i2c_master_recv(client, skb_put(*skb, len), len);
291 if (r != len) {
292 kfree_skb(*skb);
293 return -EREMOTEIO;
294 }
295
296 r = check_crc((*skb)->data, (*skb)->len);
297 if (r != 0) {
298 kfree_skb(*skb);
299 r = -EBADMSG;
300 goto flush;
301 }
302
303 skb_pull(*skb, 1);
304 skb_trim(*skb, (*skb)->len - 2);
305
306 usleep_range(3000, 6000);
307
308 return 0;
309
310flush:
311 if (i2c_master_recv(client, tmp, sizeof(tmp)) < 0)
312 r = -EREMOTEIO;
313
314 usleep_range(3000, 6000);
315
316 return r;
317}
318
319/*
320 * Reads an shdlc frame from the chip. This is not as straightforward as it
321 * seems. There are cases where we could loose the frame start synchronization.
322 * The frame format is len-data-crc, and corruption can occur anywhere while
323 * transiting on i2c bus, such that we could read an invalid len.
324 * In order to recover synchronization with the next frame, we must be sure
325 * to read the real amount of data without using the len byte. We do this by
326 * assuming the following:
327 * - the chip will always present only one single complete frame on the bus
328 * before triggering the interrupt
329 * - the chip will not present a new frame until we have completely read
330 * the previous one (or until we have handled the interrupt).
331 * The tricky case is when we read a corrupted len that is less than the real
332 * len. We must detect this here in order to determine that we need to flush
333 * the bus. This is the reason why we check the crc here.
334 */
335static irqreturn_t pn544_hci_irq_thread_fn(int irq, void *dev_id)
336{
337 struct pn544_hci_info *info = dev_id;
338 struct i2c_client *client = info->i2c_dev;
339 struct sk_buff *skb = NULL;
340 int r;
341
342 BUG_ON(!info);
343 BUG_ON(irq != info->i2c_dev->irq);
344
345 dev_dbg(&client->dev, "IRQ\n");
346
347 if (info->hard_fault != 0)
348 return IRQ_HANDLED;
349
350 r = pn544_hci_i2c_read(client, &skb);
351 if (r == -EREMOTEIO) {
352 info->hard_fault = r;
353
354 nfc_shdlc_recv_frame(info->shdlc, NULL);
355
356 return IRQ_HANDLED;
357 } else if ((r == -ENOMEM) || (r == -EBADMSG)) {
358 return IRQ_HANDLED;
359 }
360
361 nfc_shdlc_recv_frame(info->shdlc, skb);
362
363 return IRQ_HANDLED;
364}
365
366static int pn544_hci_open(struct nfc_shdlc *shdlc)
367{
368 struct pn544_hci_info *info = nfc_shdlc_get_clientdata(shdlc);
369 int r = 0;
370
371 mutex_lock(&info->info_lock);
372
373 if (info->state != PN544_ST_COLD) {
374 r = -EBUSY;
375 goto out;
376 }
377
378 r = pn544_hci_enable(info, HCI_MODE);
379
380out:
381 mutex_unlock(&info->info_lock);
382 return r;
383}
384
385static void pn544_hci_close(struct nfc_shdlc *shdlc)
386{
387 struct pn544_hci_info *info = nfc_shdlc_get_clientdata(shdlc);
388
389 mutex_lock(&info->info_lock);
390
391 if (info->state == PN544_ST_COLD)
392 goto out;
393
394 pn544_hci_disable(info);
395
396out:
397 mutex_unlock(&info->info_lock);
398}
399
400static int pn544_hci_ready(struct nfc_shdlc *shdlc)
401{
402 struct nfc_hci_dev *hdev = nfc_shdlc_get_hci_dev(shdlc);
403 struct sk_buff *skb;
404 static struct hw_config {
405 u8 adr[2];
406 u8 value;
407 } hw_config[] = {
408 {{0x9f, 0x9a}, 0x00},
409
410 {{0x98, 0x10}, 0xbc},
411
412 {{0x9e, 0x71}, 0x00},
413
414 {{0x98, 0x09}, 0x00},
415
416 {{0x9e, 0xb4}, 0x00},
417
418 {{0x9e, 0xd9}, 0xff},
419 {{0x9e, 0xda}, 0xff},
420 {{0x9e, 0xdb}, 0x23},
421 {{0x9e, 0xdc}, 0x21},
422 {{0x9e, 0xdd}, 0x22},
423 {{0x9e, 0xde}, 0x24},
424
425 {{0x9c, 0x01}, 0x08},
426
427 {{0x9e, 0xaa}, 0x01},
428
429 {{0x9b, 0xd1}, 0x0d},
430 {{0x9b, 0xd2}, 0x24},
431 {{0x9b, 0xd3}, 0x0a},
432 {{0x9b, 0xd4}, 0x22},
433 {{0x9b, 0xd5}, 0x08},
434 {{0x9b, 0xd6}, 0x1e},
435 {{0x9b, 0xdd}, 0x1c},
436
437 {{0x9b, 0x84}, 0x13},
438 {{0x99, 0x81}, 0x7f},
439 {{0x99, 0x31}, 0x70},
440
441 {{0x98, 0x00}, 0x3f},
442
443 {{0x9f, 0x09}, 0x00},
444
445 {{0x9f, 0x0a}, 0x05},
446
447 {{0x9e, 0xd1}, 0xa1},
448 {{0x99, 0x23}, 0x00},
449
450 {{0x9e, 0x74}, 0x80},
451
452 {{0x9f, 0x28}, 0x10},
453
454 {{0x9f, 0x35}, 0x14},
455
456 {{0x9f, 0x36}, 0x60},
457
458 {{0x9c, 0x31}, 0x00},
459
460 {{0x9c, 0x32}, 0xc8},
461
462 {{0x9c, 0x19}, 0x40},
463
464 {{0x9c, 0x1a}, 0x40},
465
466 {{0x9c, 0x0c}, 0x00},
467
468 {{0x9c, 0x0d}, 0x00},
469
470 {{0x9c, 0x12}, 0x00},
471
472 {{0x9c, 0x13}, 0x00},
473
474 {{0x98, 0xa2}, 0x0e},
475
476 {{0x98, 0x93}, 0x40},
477
478 {{0x98, 0x7d}, 0x02},
479 {{0x98, 0x7e}, 0x00},
480 {{0x9f, 0xc8}, 0x01},
481 };
482 struct hw_config *p = hw_config;
483 int count = ARRAY_SIZE(hw_config);
484 struct sk_buff *res_skb;
485 u8 param[4];
486 int r;
487
488 param[0] = 0;
489 while (count--) {
490 param[1] = p->adr[0];
491 param[2] = p->adr[1];
492 param[3] = p->value;
493
494 r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE, PN544_WRITE,
495 param, 4, &res_skb);
496 if (r < 0)
497 return r;
498
499 if (res_skb->len != 1) {
500 kfree_skb(res_skb);
501 return -EPROTO;
502 }
503
504 if (res_skb->data[0] != p->value) {
505 kfree_skb(res_skb);
506 return -EIO;
507 }
508
509 kfree_skb(res_skb);
510
511 p++;
512 }
513
514 param[0] = NFC_HCI_UICC_HOST_ID;
515 r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE,
516 NFC_HCI_ADMIN_WHITELIST, param, 1);
517 if (r < 0)
518 return r;
519
520 param[0] = 0x3d;
521 r = nfc_hci_set_param(hdev, PN544_SYS_MGMT_GATE,
522 PN544_SYS_MGMT_INFO_NOTIFICATION, param, 1);
523 if (r < 0)
524 return r;
525
526 param[0] = 0x0;
527 r = nfc_hci_set_param(hdev, NFC_HCI_RF_READER_A_GATE,
528 PN544_RF_READER_A_AUTO_ACTIVATION, param, 1);
529 if (r < 0)
530 return r;
531
532 r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
533 NFC_HCI_EVT_END_OPERATION, NULL, 0);
534 if (r < 0)
535 return r;
536
537 param[0] = 0x1;
538 r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
539 PN544_PL_NFCT_DEACTIVATED, param, 1);
540 if (r < 0)
541 return r;
542
543 param[0] = 0x0;
544 r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
545 PN544_PL_RDPHASES, param, 1);
546 if (r < 0)
547 return r;
548
549 r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE,
550 PN544_ID_MGMT_FULL_VERSION_SW, &skb);
551 if (r < 0)
552 return r;
553
554 if (skb->len != FULL_VERSION_LEN) {
555 kfree_skb(skb);
556 return -EINVAL;
557 }
558
559 print_hex_dump(KERN_DEBUG, "FULL VERSION SOFTWARE INFO: ",
560 DUMP_PREFIX_NONE, 16, 1,
561 skb->data, FULL_VERSION_LEN, false);
562
563 kfree_skb(skb);
564
565 return 0;
566}
567
568static int pn544_hci_xmit(struct nfc_shdlc *shdlc, struct sk_buff *skb)
569{
570 struct pn544_hci_info *info = nfc_shdlc_get_clientdata(shdlc);
571 struct i2c_client *client = info->i2c_dev;
572
573 if (info->hard_fault != 0)
574 return info->hard_fault;
575
576 return pn544_hci_i2c_write(client, skb->data, skb->len);
577}
578
579static int pn544_hci_start_poll(struct nfc_shdlc *shdlc, u32 protocols)
580{
581 struct nfc_hci_dev *hdev = nfc_shdlc_get_hci_dev(shdlc);
582 u8 phases = 0;
583 int r;
584 u8 duration[2];
585 u8 activated;
586
587 pr_info(DRIVER_DESC ": %s protocols = %d\n", __func__, protocols);
588
589 r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
590 NFC_HCI_EVT_END_OPERATION, NULL, 0);
591 if (r < 0)
592 return r;
593
594 duration[0] = 0x18;
595 duration[1] = 0x6a;
596 r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
597 PN544_PL_EMULATION, duration, 2);
598 if (r < 0)
599 return r;
600
601 activated = 0;
602 r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
603 PN544_PL_NFCT_DEACTIVATED, &activated, 1);
604 if (r < 0)
605 return r;
606
607 if (protocols & (NFC_PROTO_ISO14443_MASK | NFC_PROTO_MIFARE_MASK |
608 NFC_PROTO_JEWEL_MASK))
609 phases |= 1; /* Type A */
610 if (protocols & NFC_PROTO_FELICA_MASK) {
611 phases |= (1 << 2); /* Type F 212 */
612 phases |= (1 << 3); /* Type F 424 */
613 }
614
615 phases |= (1 << 5); /* NFC active */
616
617 r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
618 PN544_PL_RDPHASES, &phases, 1);
619 if (r < 0)
620 return r;
621
622 r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
623 NFC_HCI_EVT_READER_REQUESTED, NULL, 0);
624 if (r < 0)
625 nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
626 NFC_HCI_EVT_END_OPERATION, NULL, 0);
627
628 return r;
629}
630
631static int pn544_hci_target_from_gate(struct nfc_shdlc *shdlc, u8 gate,
632 struct nfc_target *target)
633{
634 switch (gate) {
635 case PN544_RF_READER_F_GATE:
636 target->supported_protocols = NFC_PROTO_FELICA_MASK;
637 break;
638 case PN544_RF_READER_JEWEL_GATE:
639 target->supported_protocols = NFC_PROTO_JEWEL_MASK;
640 target->sens_res = 0x0c00;
641 break;
642 default:
643 return -EPROTO;
644 }
645
646 return 0;
647}
648
649static int pn544_hci_complete_target_discovered(struct nfc_shdlc *shdlc,
650 u8 gate,
651 struct nfc_target *target)
652{
653 struct nfc_hci_dev *hdev = nfc_shdlc_get_hci_dev(shdlc);
654 struct sk_buff *uid_skb;
655 int r = 0;
656
657 if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) {
658 if (target->nfcid1_len != 4 && target->nfcid1_len != 7 &&
659 target->nfcid1_len != 10)
660 return -EPROTO;
661
662 r = nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE,
663 PN544_RF_READER_CMD_ACTIVATE_NEXT,
664 target->nfcid1, target->nfcid1_len, NULL);
665 } else if (target->supported_protocols & NFC_PROTO_FELICA_MASK) {
666 r = nfc_hci_get_param(hdev, PN544_RF_READER_F_GATE,
667 PN544_FELICA_ID, &uid_skb);
668 if (r < 0)
669 return r;
670
671 if (uid_skb->len != 8) {
672 kfree_skb(uid_skb);
673 return -EPROTO;
674 }
675
676 r = nfc_hci_send_cmd(hdev, PN544_RF_READER_F_GATE,
677 PN544_RF_READER_CMD_ACTIVATE_NEXT,
678 uid_skb->data, uid_skb->len, NULL);
679 kfree_skb(uid_skb);
680 } else if (target->supported_protocols & NFC_PROTO_ISO14443_MASK) {
681 /*
682 * TODO: maybe other ISO 14443 require some kind of continue
683 * activation, but for now we've seen only this one below.
684 */
685 if (target->sens_res == 0x4403) /* Type 4 Mifare DESFire */
686 r = nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE,
687 PN544_RF_READER_A_CMD_CONTINUE_ACTIVATION,
688 NULL, 0, NULL);
689 }
690
691 return r;
692}
693
694#define MIFARE_CMD_AUTH_KEY_A 0x60
695#define MIFARE_CMD_AUTH_KEY_B 0x61
696#define MIFARE_CMD_HEADER 2
697#define MIFARE_UID_LEN 4
698#define MIFARE_KEY_LEN 6
699#define MIFARE_CMD_LEN 12
700/*
701 * Returns:
702 * <= 0: driver handled the data exchange
703 * 1: driver doesn't especially handle, please do standard processing
704 */
705static int pn544_hci_data_exchange(struct nfc_shdlc *shdlc,
706 struct nfc_target *target,
707 struct sk_buff *skb,
708 struct sk_buff **res_skb)
709{
710 struct nfc_hci_dev *hdev = nfc_shdlc_get_hci_dev(shdlc);
711 int r;
712
713 pr_info(DRIVER_DESC ": %s for gate=%d\n", __func__,
714 target->hci_reader_gate);
715
716 switch (target->hci_reader_gate) {
717 case NFC_HCI_RF_READER_A_GATE:
718 if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) {
719 /*
720 * It seems that pn544 is inverting key and UID for
721 * MIFARE authentication commands.
722 */
723 if (skb->len == MIFARE_CMD_LEN &&
724 (skb->data[0] == MIFARE_CMD_AUTH_KEY_A ||
725 skb->data[0] == MIFARE_CMD_AUTH_KEY_B)) {
726 u8 uid[MIFARE_UID_LEN];
727 u8 *data = skb->data + MIFARE_CMD_HEADER;
728
729 memcpy(uid, data + MIFARE_KEY_LEN,
730 MIFARE_UID_LEN);
731 memmove(data + MIFARE_UID_LEN, data,
732 MIFARE_KEY_LEN);
733 memcpy(data, uid, MIFARE_UID_LEN);
734 }
735
736 return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
737 PN544_MIFARE_CMD,
738 skb->data, skb->len, res_skb);
739 } else
740 return 1;
741 case PN544_RF_READER_F_GATE:
742 *skb_push(skb, 1) = 0;
743 *skb_push(skb, 1) = 0;
744
745 r = nfc_hci_send_cmd(hdev, target->hci_reader_gate,
746 PN544_FELICA_RAW,
747 skb->data, skb->len, res_skb);
748 if (r == 0)
749 skb_pull(*res_skb, 1);
750 return r;
751 case PN544_RF_READER_JEWEL_GATE:
752 return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
753 PN544_JEWEL_RAW_CMD,
754 skb->data, skb->len, res_skb);
755 default:
756 return 1;
757 }
758}
759
760static int pn544_hci_check_presence(struct nfc_shdlc *shdlc,
761 struct nfc_target *target)
762{
763 struct nfc_hci_dev *hdev = nfc_shdlc_get_hci_dev(shdlc);
764
765 return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
766 PN544_RF_READER_CMD_PRESENCE_CHECK,
767 NULL, 0, NULL);
768}
769
770static struct nfc_shdlc_ops pn544_shdlc_ops = {
771 .open = pn544_hci_open,
772 .close = pn544_hci_close,
773 .hci_ready = pn544_hci_ready,
774 .xmit = pn544_hci_xmit,
775 .start_poll = pn544_hci_start_poll,
776 .target_from_gate = pn544_hci_target_from_gate,
777 .complete_target_discovered = pn544_hci_complete_target_discovered,
778 .data_exchange = pn544_hci_data_exchange,
779 .check_presence = pn544_hci_check_presence,
780};
781
782static int __devinit pn544_hci_probe(struct i2c_client *client,
783 const struct i2c_device_id *id)
784{
785 struct pn544_hci_info *info;
786 struct pn544_nfc_platform_data *pdata;
787 int r = 0;
788 u32 protocols;
789 struct nfc_hci_init_data init_data;
790
791 dev_dbg(&client->dev, "%s\n", __func__);
792 dev_dbg(&client->dev, "IRQ: %d\n", client->irq);
793
794 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
795 dev_err(&client->dev, "Need I2C_FUNC_I2C\n");
796 return -ENODEV;
797 }
798
799 info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL);
800 if (!info) {
801 dev_err(&client->dev,
802 "Cannot allocate memory for pn544_hci_info.\n");
803 r = -ENOMEM;
804 goto err_info_alloc;
805 }
806
807 info->i2c_dev = client;
808 info->state = PN544_ST_COLD;
809 mutex_init(&info->info_lock);
810 i2c_set_clientdata(client, info);
811
812 pdata = client->dev.platform_data;
813 if (pdata == NULL) {
814 dev_err(&client->dev, "No platform data\n");
815 r = -EINVAL;
816 goto err_pdata;
817 }
818
819 if (pdata->request_resources == NULL) {
820 dev_err(&client->dev, "request_resources() missing\n");
821 r = -EINVAL;
822 goto err_pdata;
823 }
824
825 r = pdata->request_resources(client);
826 if (r) {
827 dev_err(&client->dev, "Cannot get platform resources\n");
828 goto err_pdata;
829 }
830
831 info->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE);
832 info->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET);
833 info->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ);
834
835 pn544_hci_platform_init(info);
836
837 r = request_threaded_irq(client->irq, NULL, pn544_hci_irq_thread_fn,
838 IRQF_TRIGGER_RISING, PN544_HCI_DRIVER_NAME,
839 info);
840 if (r < 0) {
841 dev_err(&client->dev, "Unable to register IRQ handler\n");
842 goto err_rti;
843 }
844
845 init_data.gate_count = ARRAY_SIZE(pn544_custom_gates);
846
847 memcpy(init_data.gates, pn544_custom_gates,
848 ARRAY_SIZE(pn544_custom_gates));
849
850 /*
851 * TODO: Session id must include the driver name + some bus addr
852 * persistent info to discriminate 2 identical chips
853 */
854 strcpy(init_data.session_id, "ID544HCI");
855
856 protocols = NFC_PROTO_JEWEL_MASK |
857 NFC_PROTO_MIFARE_MASK |
858 NFC_PROTO_FELICA_MASK |
859 NFC_PROTO_ISO14443_MASK |
860 NFC_PROTO_NFC_DEP_MASK;
861
862 info->shdlc = nfc_shdlc_allocate(&pn544_shdlc_ops,
863 &init_data, protocols,
864 PN544_CMDS_HEADROOM, 0,
865 PN544_HCI_LLC_MAX_PAYLOAD,
866 dev_name(&client->dev));
867 if (!info->shdlc) {
868 dev_err(&client->dev, "Cannot allocate nfc shdlc.\n");
869 r = -ENOMEM;
870 goto err_allocshdlc;
871 }
872
873 nfc_shdlc_set_clientdata(info->shdlc, info);
874
875 return 0;
876
877err_allocshdlc:
878 free_irq(client->irq, info);
879
880err_rti:
881 if (pdata->free_resources != NULL)
882 pdata->free_resources();
883
884err_pdata:
885 kfree(info);
886
887err_info_alloc:
888 return r;
889}
890
891static __devexit int pn544_hci_remove(struct i2c_client *client)
892{
893 struct pn544_hci_info *info = i2c_get_clientdata(client);
894 struct pn544_nfc_platform_data *pdata = client->dev.platform_data;
895
896 dev_dbg(&client->dev, "%s\n", __func__);
897
898 nfc_shdlc_free(info->shdlc);
899
900 if (info->state != PN544_ST_COLD) {
901 if (pdata->disable)
902 pdata->disable();
903 }
904
905 free_irq(client->irq, info);
906 if (pdata->free_resources)
907 pdata->free_resources();
908
909 kfree(info);
910
911 return 0;
912}
913
914static struct i2c_driver pn544_hci_driver = {
915 .driver = {
916 .name = PN544_HCI_DRIVER_NAME,
917 },
918 .probe = pn544_hci_probe,
919 .id_table = pn544_hci_id_table,
920 .remove = __devexit_p(pn544_hci_remove),
921};
922
923static int __init pn544_hci_init(void)
924{
925 int r;
926
927 pr_debug(DRIVER_DESC ": %s\n", __func__);
928
929 r = i2c_add_driver(&pn544_hci_driver);
930 if (r) {
931 pr_err(PN544_HCI_DRIVER_NAME ": driver registration failed\n");
932 return r;
933 }
934
935 return 0;
936}
937
938static void __exit pn544_hci_exit(void)
939{
940 i2c_del_driver(&pn544_hci_driver);
941}
942
943module_init(pn544_hci_init);
944module_exit(pn544_hci_exit);
945
946MODULE_LICENSE("GPL");
947MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c
index bad7ba517a1c..f551e5376147 100644
--- a/drivers/ssb/b43_pci_bridge.c
+++ b/drivers/ssb/b43_pci_bridge.c
@@ -29,6 +29,8 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = {
29 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) }, 29 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
30 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) }, 30 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
31 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) }, 31 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
32 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4322) },
33 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43222) },
32 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) }, 34 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) },
33 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) }, 35 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) },
34 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4328) }, 36 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4328) },
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index ed4124469a3a..e9d94968f394 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -178,6 +178,18 @@ err_pci:
178#define SPEX(_outvar, _offset, _mask, _shift) \ 178#define SPEX(_outvar, _offset, _mask, _shift) \
179 SPEX16(_outvar, _offset, _mask, _shift) 179 SPEX16(_outvar, _offset, _mask, _shift)
180 180
181#define SPEX_ARRAY8(_field, _offset, _mask, _shift) \
182 do { \
183 SPEX(_field[0], _offset + 0, _mask, _shift); \
184 SPEX(_field[1], _offset + 2, _mask, _shift); \
185 SPEX(_field[2], _offset + 4, _mask, _shift); \
186 SPEX(_field[3], _offset + 6, _mask, _shift); \
187 SPEX(_field[4], _offset + 8, _mask, _shift); \
188 SPEX(_field[5], _offset + 10, _mask, _shift); \
189 SPEX(_field[6], _offset + 12, _mask, _shift); \
190 SPEX(_field[7], _offset + 14, _mask, _shift); \
191 } while (0)
192
181 193
182static inline u8 ssb_crc8(u8 crc, u8 data) 194static inline u8 ssb_crc8(u8 crc, u8 data)
183{ 195{
@@ -360,8 +372,9 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
360 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14); 372 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
361 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15); 373 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
362 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0); 374 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
363 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, 375 if (out->revision == 1)
364 SSB_SPROM1_BINF_CCODE_SHIFT); 376 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
377 SSB_SPROM1_BINF_CCODE_SHIFT);
365 SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA, 378 SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
366 SSB_SPROM1_BINF_ANTA_SHIFT); 379 SSB_SPROM1_BINF_ANTA_SHIFT);
367 SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG, 380 SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
@@ -387,6 +400,8 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
387 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); 400 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
388 if (out->revision >= 2) 401 if (out->revision >= 2)
389 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); 402 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
403 SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8);
404 SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
390 405
391 /* Extract the antenna gain values. */ 406 /* Extract the antenna gain values. */
392 out->antenna_gain.a0 = r123_extract_antgain(out->revision, in, 407 out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
@@ -455,14 +470,17 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
455 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); 470 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
456 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, 471 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
457 SSB_SPROM4_ETHPHY_ET1A_SHIFT); 472 SSB_SPROM4_ETHPHY_ET1A_SHIFT);
473 SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0);
458 if (out->revision == 4) { 474 if (out->revision == 4) {
459 SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); 475 SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8);
476 SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0);
460 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); 477 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
461 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); 478 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
462 SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0); 479 SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
463 SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0); 480 SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
464 } else { 481 } else {
465 SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0); 482 SPEX(alpha2[0], SSB_SPROM5_CCODE, 0xff00, 8);
483 SPEX(alpha2[1], SSB_SPROM5_CCODE, 0x00ff, 0);
466 SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0); 484 SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
467 SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0); 485 SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
468 SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0); 486 SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
@@ -525,7 +543,9 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
525 v = in[SPOFF(SSB_SPROM8_IL0MAC) + i]; 543 v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
526 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); 544 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
527 } 545 }
528 SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0); 546 SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
547 SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
548 SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
529 SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0); 549 SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
530 SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0); 550 SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
531 SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0); 551 SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
@@ -655,6 +675,63 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
655 SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, 675 SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G,
656 SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); 676 SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
657 677
678 SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
679 SSB_SPROM8_LEDDC_ON_SHIFT);
680 SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
681 SSB_SPROM8_LEDDC_OFF_SHIFT);
682
683 SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
684 SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
685 SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
686 SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
687 SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
688 SSB_SPROM8_TXRXC_SWITCH_SHIFT);
689
690 SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
691
692 SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
693 SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
694 SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
695 SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
696
697 SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
698 SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
699 SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
700 SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
701 SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
702 SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
703 SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
704 SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
705 SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
706 SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
707 SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
708 SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
709 SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
710 SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
711 SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
712 SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
713 SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
714 SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
715 SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
716 SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
717
718 SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
719 SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
720 SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
721 SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
722
723 SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
724 SSB_SPROM8_THERMAL_TRESH_SHIFT);
725 SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
726 SSB_SPROM8_THERMAL_OFFSET_SHIFT);
727 SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
728 SSB_SPROM8_TEMPDELTA_PHYCAL,
729 SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
730 SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
731 SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
732 SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
733 SSB_SPROM8_TEMPDELTA_HYSTERESIS,
734 SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
658 sprom_extract_r458(out, in); 735 sprom_extract_r458(out, in);
659 736
660 /* TODO - get remaining rev 8 stuff needed */ 737 /* TODO - get remaining rev 8 stuff needed */
@@ -784,7 +861,6 @@ static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
784{ 861{
785 bi->vendor = bus->host_pci->subsystem_vendor; 862 bi->vendor = bus->host_pci->subsystem_vendor;
786 bi->type = bus->host_pci->subsystem_device; 863 bi->type = bus->host_pci->subsystem_device;
787 bi->rev = bus->host_pci->revision;
788} 864}
789 865
790int ssb_pci_get_invariants(struct ssb_bus *bus, 866int ssb_pci_get_invariants(struct ssb_bus *bus,