diff options
author | David S. Miller <davem@davemloft.net> | 2016-07-25 14:09:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-25 14:09:19 -0400 |
commit | d5b160d3422f668c0c46092889f9cd935be531e9 (patch) | |
tree | 4a375bbaf18c76862e6871a30261fd7f13025c1f | |
parent | 15657841bd5bb23dac7120c4e2e181b390a5ec12 (diff) | |
parent | cb6a115188500a448709df1f2d7698a4e1b7a099 (diff) |
Merge tag 'wireless-drivers-next-for-davem-2016-07-22' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says:
====================
pull-request: wireless-drivers-next 2016-07-22
I'm sick so I have to keep this short, but here's the last pull request
to net-next. This time there's a trivial conflict with mtd tree:
http://lkml.kernel.org/g/20160720123133.44dab209@canb.auug.org.au
We concluded with Brian (CCed) that it's best that we ask Linus to fix
this. The patches have been in linux-next for a couple of days. This
time I haven't done any merge tests so I don't know if there are any
other conflicts etc.
Please let me know if there are any problems.
wireless-drivers-next patches for 4.8
Major changes:
wl18xx
* add initial mesh support
bcma
* serial flash support on non-MIPS SoCs
ath10k
* enable support for QCA9888
* disable wake_tx_queue() mac80211 op for older devices to workaround
throughput regression
ath9k
* implement temperature compensation support for AR9003+
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
78 files changed, 1178 insertions, 644 deletions
diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt index 9180724e182c..8f9ced076fe1 100644 --- a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt +++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt | |||
@@ -1,19 +1,30 @@ | |||
1 | * Texas Instruments wl1271 wireless lan controller | 1 | * Texas Instruments wl12xx/wl18xx wireless lan controller |
2 | 2 | ||
3 | The wl1271 chip can be connected via SPI or via SDIO. This | 3 | The wl12xx/wl18xx chips can be connected via SPI or via SDIO. This |
4 | document describes the binding for the SPI connected chip. | 4 | document describes the binding for the SPI connected chip. |
5 | 5 | ||
6 | Required properties: | 6 | Required properties: |
7 | - compatible : Should be "ti,wl1271" | 7 | - compatible : Should be one of the following: |
8 | * "ti,wl1271" | ||
9 | * "ti,wl1273" | ||
10 | * "ti,wl1281" | ||
11 | * "ti,wl1283" | ||
12 | * "ti,wl1801" | ||
13 | * "ti,wl1805" | ||
14 | * "ti,wl1807" | ||
15 | * "ti,wl1831" | ||
16 | * "ti,wl1835" | ||
17 | * "ti,wl1837" | ||
8 | - reg : Chip select address of device | 18 | - reg : Chip select address of device |
9 | - spi-max-frequency : Maximum SPI clocking speed of device in Hz | 19 | - spi-max-frequency : Maximum SPI clocking speed of device in Hz |
10 | - ref-clock-frequency : Reference clock frequency | ||
11 | - interrupt-parent, interrupts : | 20 | - interrupt-parent, interrupts : |
12 | Should contain parameters for 1 interrupt line. | 21 | Should contain parameters for 1 interrupt line. |
13 | Interrupt parameters: parent, line number, type. | 22 | Interrupt parameters: parent, line number, type. |
14 | - vwlan-supply : Point the node of the regulator that powers/enable the wl1271 chip | 23 | - vwlan-supply : Point the node of the regulator that powers/enable the |
24 | wl12xx/wl18xx chip | ||
15 | 25 | ||
16 | Optional properties: | 26 | Optional properties: |
27 | - ref-clock-frequency : Reference clock frequency (should be set for wl12xx) | ||
17 | - clock-xtal : boolean, clock is generated from XTAL | 28 | - clock-xtal : boolean, clock is generated from XTAL |
18 | 29 | ||
19 | - Please consult Documentation/devicetree/bindings/spi/spi-bus.txt | 30 | - Please consult Documentation/devicetree/bindings/spi/spi-bus.txt |
@@ -21,16 +32,28 @@ Optional properties: | |||
21 | 32 | ||
22 | Examples: | 33 | Examples: |
23 | 34 | ||
35 | For wl12xx family: | ||
24 | &spi1 { | 36 | &spi1 { |
25 | wl1271@1 { | 37 | wlcore: wlcore@1 { |
26 | compatible = "ti,wl1271"; | 38 | compatible = "ti,wl1271"; |
27 | |||
28 | reg = <1>; | 39 | reg = <1>; |
29 | spi-max-frequency = <48000000>; | 40 | spi-max-frequency = <48000000>; |
30 | clock-xtal; | ||
31 | ref-clock-frequency = <38400000>; | ||
32 | interrupt-parent = <&gpio3>; | 41 | interrupt-parent = <&gpio3>; |
33 | interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; | 42 | interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; |
34 | vwlan-supply = <&vwlan_fixed>; | 43 | vwlan-supply = <&vwlan_fixed>; |
44 | clock-xtal; | ||
45 | ref-clock-frequency = <38400000>; | ||
46 | }; | ||
47 | }; | ||
48 | |||
49 | For wl18xx family: | ||
50 | &spi0 { | ||
51 | wlcore: wlcore@0 { | ||
52 | compatible = "ti,wl1835"; | ||
53 | reg = <0>; | ||
54 | spi-max-frequency = <48000000>; | ||
55 | interrupt-parent = <&gpio0>; | ||
56 | interrupts = <27 IRQ_TYPE_EDGE_RISING>; | ||
57 | vwlan-supply = <&vwlan_fixed>; | ||
35 | }; | 58 | }; |
36 | }; | 59 | }; |
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig index efdc2ae8441a..b5c48a8d485f 100644 --- a/drivers/bcma/Kconfig +++ b/drivers/bcma/Kconfig | |||
@@ -76,9 +76,16 @@ config BCMA_PFLASH | |||
76 | default y | 76 | default y |
77 | 77 | ||
78 | config BCMA_SFLASH | 78 | config BCMA_SFLASH |
79 | bool | 79 | bool "ChipCommon-attached serial flash support" |
80 | depends on BCMA_DRIVER_MIPS | 80 | depends on BCMA_HOST_SOC |
81 | default y | 81 | default y |
82 | help | ||
83 | Some cheap devices have serial flash connected to the ChipCommon | ||
84 | instead of independent SPI controller. It requires using a separated | ||
85 | driver that implements ChipCommon specific interface communication. | ||
86 | |||
87 | Enabling this symbol will let bcma recognize serial flash and register | ||
88 | it as platform device. | ||
82 | 89 | ||
83 | config BCMA_NFLASH | 90 | config BCMA_NFLASH |
84 | bool | 91 | bool |
diff --git a/drivers/bcma/driver_chipcommon_b.c b/drivers/bcma/driver_chipcommon_b.c index c20b5f4ff290..57f10b58b47c 100644 --- a/drivers/bcma/driver_chipcommon_b.c +++ b/drivers/bcma/driver_chipcommon_b.c | |||
@@ -33,11 +33,12 @@ static bool bcma_wait_reg(struct bcma_bus *bus, void __iomem *addr, u32 mask, | |||
33 | void bcma_chipco_b_mii_write(struct bcma_drv_cc_b *ccb, u32 offset, u32 value) | 33 | void bcma_chipco_b_mii_write(struct bcma_drv_cc_b *ccb, u32 offset, u32 value) |
34 | { | 34 | { |
35 | struct bcma_bus *bus = ccb->core->bus; | 35 | struct bcma_bus *bus = ccb->core->bus; |
36 | void __iomem *mii = ccb->mii; | ||
36 | 37 | ||
37 | writel(offset, ccb->mii + 0x00); | 38 | writel(offset, mii + BCMA_CCB_MII_MNG_CTL); |
38 | bcma_wait_reg(bus, ccb->mii + 0x00, 0x0100, 0x0000, 100); | 39 | bcma_wait_reg(bus, mii + BCMA_CCB_MII_MNG_CTL, 0x0100, 0x0000, 100); |
39 | writel(value, ccb->mii + 0x04); | 40 | writel(value, mii + BCMA_CCB_MII_MNG_CMD_DATA); |
40 | bcma_wait_reg(bus, ccb->mii + 0x00, 0x0100, 0x0000, 100); | 41 | bcma_wait_reg(bus, mii + BCMA_CCB_MII_MNG_CTL, 0x0100, 0x0000, 100); |
41 | } | 42 | } |
42 | EXPORT_SYMBOL_GPL(bcma_chipco_b_mii_write); | 43 | EXPORT_SYMBOL_GPL(bcma_chipco_b_mii_write); |
43 | 44 | ||
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index cae5385cf499..bd46569e0e52 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
@@ -295,6 +295,7 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = { | |||
295 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, | 295 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, |
296 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) }, | 296 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) }, |
297 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_DELL, 0x0016) }, | 297 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_DELL, 0x0016) }, |
298 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_FOXCONN, 0xe092) }, | ||
298 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) }, | 299 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) }, |
299 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, | 300 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, |
300 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, | 301 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, |
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index f73c41697a00..64a248556d29 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig | |||
@@ -114,7 +114,7 @@ config MTD_SST25L | |||
114 | 114 | ||
115 | config MTD_BCM47XXSFLASH | 115 | config MTD_BCM47XXSFLASH |
116 | tristate "R/O support for serial flash on BCMA bus" | 116 | tristate "R/O support for serial flash on BCMA bus" |
117 | depends on BCMA_SFLASH | 117 | depends on BCMA_SFLASH && (MIPS || ARM) |
118 | help | 118 | help |
119 | BCMA bus can have various flash memories attached, they are | 119 | BCMA bus can have various flash memories attached, they are |
120 | registered by bcma as platform devices. This enables driver for | 120 | registered by bcma as platform devices. This enables driver for |
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index dfb3db0ee5d1..e88982921aa3 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
@@ -207,6 +207,28 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { | |||
207 | }, | 207 | }, |
208 | }, | 208 | }, |
209 | { | 209 | { |
210 | .id = QCA9888_HW_2_0_DEV_VERSION, | ||
211 | .dev_id = QCA9888_2_0_DEVICE_ID, | ||
212 | .name = "qca9888 hw2.0", | ||
213 | .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR, | ||
214 | .uart_pin = 7, | ||
215 | .otp_exe_param = 0x00000700, | ||
216 | .continuous_frag_desc = true, | ||
217 | .channel_counters_freq_hz = 150000, | ||
218 | .max_probe_resp_desc_thres = 24, | ||
219 | .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE, | ||
220 | .tx_chain_mask = 3, | ||
221 | .rx_chain_mask = 3, | ||
222 | .max_spatial_stream = 2, | ||
223 | .cal_data_len = 12064, | ||
224 | .fw = { | ||
225 | .dir = QCA9888_HW_2_0_FW_DIR, | ||
226 | .board = QCA9888_HW_2_0_BOARD_DATA_FILE, | ||
227 | .board_size = QCA99X0_BOARD_DATA_SZ, | ||
228 | .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ, | ||
229 | }, | ||
230 | }, | ||
231 | { | ||
210 | .id = QCA9377_HW_1_0_DEV_VERSION, | 232 | .id = QCA9377_HW_1_0_DEV_VERSION, |
211 | .dev_id = QCA9377_1_0_DEVICE_ID, | 233 | .dev_id = QCA9377_1_0_DEVICE_ID, |
212 | .name = "qca9377 hw1.0", | 234 | .name = "qca9377 hw1.0", |
@@ -1675,7 +1697,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) | |||
1675 | case ATH10K_FW_WMI_OP_VERSION_10_4: | 1697 | case ATH10K_FW_WMI_OP_VERSION_10_4: |
1676 | case ATH10K_FW_WMI_OP_VERSION_UNSET: | 1698 | case ATH10K_FW_WMI_OP_VERSION_UNSET: |
1677 | case ATH10K_FW_WMI_OP_VERSION_MAX: | 1699 | case ATH10K_FW_WMI_OP_VERSION_MAX: |
1678 | WARN_ON(1); | 1700 | ath10k_err(ar, "htt op version not found from fw meta data"); |
1679 | return -EINVAL; | 1701 | return -EINVAL; |
1680 | } | 1702 | } |
1681 | } | 1703 | } |
@@ -2171,6 +2193,10 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, | |||
2171 | ar->regs = &qca99x0_regs; | 2193 | ar->regs = &qca99x0_regs; |
2172 | ar->hw_values = &qca99x0_values; | 2194 | ar->hw_values = &qca99x0_values; |
2173 | break; | 2195 | break; |
2196 | case ATH10K_HW_QCA9888: | ||
2197 | ar->regs = &qca99x0_regs; | ||
2198 | ar->hw_values = &qca9888_values; | ||
2199 | break; | ||
2174 | case ATH10K_HW_QCA4019: | 2200 | case ATH10K_HW_QCA4019: |
2175 | ar->regs = &qca4019_regs; | 2201 | ar->regs = &qca4019_regs; |
2176 | ar->hw_values = &qca4019_values; | 2202 | ar->hw_values = &qca4019_values; |
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 3da18c9dbd7a..30ae5bf81611 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -165,6 +165,13 @@ struct ath10k_fw_stats_peer { | |||
165 | u32 rx_duration; | 165 | u32 rx_duration; |
166 | }; | 166 | }; |
167 | 167 | ||
168 | struct ath10k_fw_extd_stats_peer { | ||
169 | struct list_head list; | ||
170 | |||
171 | u8 peer_macaddr[ETH_ALEN]; | ||
172 | u32 rx_duration; | ||
173 | }; | ||
174 | |||
168 | struct ath10k_fw_stats_vdev { | 175 | struct ath10k_fw_stats_vdev { |
169 | struct list_head list; | 176 | struct list_head list; |
170 | 177 | ||
@@ -256,9 +263,11 @@ struct ath10k_fw_stats_pdev { | |||
256 | }; | 263 | }; |
257 | 264 | ||
258 | struct ath10k_fw_stats { | 265 | struct ath10k_fw_stats { |
266 | bool extended; | ||
259 | struct list_head pdevs; | 267 | struct list_head pdevs; |
260 | struct list_head vdevs; | 268 | struct list_head vdevs; |
261 | struct list_head peers; | 269 | struct list_head peers; |
270 | struct list_head peers_extd; | ||
262 | }; | 271 | }; |
263 | 272 | ||
264 | #define ATH10K_TPC_TABLE_TYPE_FLAG 1 | 273 | #define ATH10K_TPC_TABLE_TYPE_FLAG 1 |
@@ -667,6 +676,7 @@ struct ath10k_fw_components { | |||
667 | struct ath10k { | 676 | struct ath10k { |
668 | struct ath_common ath_common; | 677 | struct ath_common ath_common; |
669 | struct ieee80211_hw *hw; | 678 | struct ieee80211_hw *hw; |
679 | struct ieee80211_ops *ops; | ||
670 | struct device *dev; | 680 | struct device *dev; |
671 | u8 mac_addr[ETH_ALEN]; | 681 | u8 mac_addr[ETH_ALEN]; |
672 | 682 | ||
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 8fbb8f2c7828..355e1ae665f9 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c | |||
@@ -313,13 +313,25 @@ static void ath10k_fw_stats_peers_free(struct list_head *head) | |||
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
316 | static void ath10k_fw_extd_stats_peers_free(struct list_head *head) | ||
317 | { | ||
318 | struct ath10k_fw_extd_stats_peer *i, *tmp; | ||
319 | |||
320 | list_for_each_entry_safe(i, tmp, head, list) { | ||
321 | list_del(&i->list); | ||
322 | kfree(i); | ||
323 | } | ||
324 | } | ||
325 | |||
316 | static void ath10k_debug_fw_stats_reset(struct ath10k *ar) | 326 | static void ath10k_debug_fw_stats_reset(struct ath10k *ar) |
317 | { | 327 | { |
318 | spin_lock_bh(&ar->data_lock); | 328 | spin_lock_bh(&ar->data_lock); |
319 | ar->debug.fw_stats_done = false; | 329 | ar->debug.fw_stats_done = false; |
330 | ar->debug.fw_stats.extended = false; | ||
320 | ath10k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); | 331 | ath10k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); |
321 | ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs); | 332 | ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs); |
322 | ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers); | 333 | ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers); |
334 | ath10k_fw_extd_stats_peers_free(&ar->debug.fw_stats.peers_extd); | ||
323 | spin_unlock_bh(&ar->data_lock); | 335 | spin_unlock_bh(&ar->data_lock); |
324 | } | 336 | } |
325 | 337 | ||
@@ -334,6 +346,7 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) | |||
334 | INIT_LIST_HEAD(&stats.pdevs); | 346 | INIT_LIST_HEAD(&stats.pdevs); |
335 | INIT_LIST_HEAD(&stats.vdevs); | 347 | INIT_LIST_HEAD(&stats.vdevs); |
336 | INIT_LIST_HEAD(&stats.peers); | 348 | INIT_LIST_HEAD(&stats.peers); |
349 | INIT_LIST_HEAD(&stats.peers_extd); | ||
337 | 350 | ||
338 | spin_lock_bh(&ar->data_lock); | 351 | spin_lock_bh(&ar->data_lock); |
339 | ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats); | 352 | ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats); |
@@ -354,7 +367,7 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) | |||
354 | * delivered which is treated as end-of-data and is itself discarded | 367 | * delivered which is treated as end-of-data and is itself discarded |
355 | */ | 368 | */ |
356 | if (ath10k_peer_stats_enabled(ar)) | 369 | if (ath10k_peer_stats_enabled(ar)) |
357 | ath10k_sta_update_rx_duration(ar, &stats.peers); | 370 | ath10k_sta_update_rx_duration(ar, &stats); |
358 | 371 | ||
359 | if (ar->debug.fw_stats_done) { | 372 | if (ar->debug.fw_stats_done) { |
360 | if (!ath10k_peer_stats_enabled(ar)) | 373 | if (!ath10k_peer_stats_enabled(ar)) |
@@ -396,6 +409,8 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) | |||
396 | 409 | ||
397 | list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers); | 410 | list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers); |
398 | list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs); | 411 | list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs); |
412 | list_splice_tail_init(&stats.peers_extd, | ||
413 | &ar->debug.fw_stats.peers_extd); | ||
399 | } | 414 | } |
400 | 415 | ||
401 | complete(&ar->debug.fw_stats_complete); | 416 | complete(&ar->debug.fw_stats_complete); |
@@ -407,6 +422,7 @@ free: | |||
407 | ath10k_fw_stats_pdevs_free(&stats.pdevs); | 422 | ath10k_fw_stats_pdevs_free(&stats.pdevs); |
408 | ath10k_fw_stats_vdevs_free(&stats.vdevs); | 423 | ath10k_fw_stats_vdevs_free(&stats.vdevs); |
409 | ath10k_fw_stats_peers_free(&stats.peers); | 424 | ath10k_fw_stats_peers_free(&stats.peers); |
425 | ath10k_fw_extd_stats_peers_free(&stats.peers_extd); | ||
410 | 426 | ||
411 | spin_unlock_bh(&ar->data_lock); | 427 | spin_unlock_bh(&ar->data_lock); |
412 | } | 428 | } |
@@ -2330,6 +2346,7 @@ int ath10k_debug_create(struct ath10k *ar) | |||
2330 | INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); | 2346 | INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); |
2331 | INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs); | 2347 | INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs); |
2332 | INIT_LIST_HEAD(&ar->debug.fw_stats.peers); | 2348 | INIT_LIST_HEAD(&ar->debug.fw_stats.peers); |
2349 | INIT_LIST_HEAD(&ar->debug.fw_stats.peers_extd); | ||
2333 | 2350 | ||
2334 | return 0; | 2351 | return 0; |
2335 | } | 2352 | } |
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index 75c89e3625ef..c458fa96a6d4 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h | |||
@@ -154,10 +154,15 @@ ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) | |||
154 | #ifdef CONFIG_MAC80211_DEBUGFS | 154 | #ifdef CONFIG_MAC80211_DEBUGFS |
155 | void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 155 | void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
156 | struct ieee80211_sta *sta, struct dentry *dir); | 156 | struct ieee80211_sta *sta, struct dentry *dir); |
157 | void ath10k_sta_update_rx_duration(struct ath10k *ar, struct list_head *peer); | 157 | void ath10k_sta_update_rx_duration(struct ath10k *ar, |
158 | struct ath10k_fw_stats *stats); | ||
159 | void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
160 | struct ieee80211_sta *sta, | ||
161 | struct station_info *sinfo); | ||
158 | #else | 162 | #else |
159 | static inline void ath10k_sta_update_rx_duration(struct ath10k *ar, | 163 | static inline |
160 | struct list_head *peer) | 164 | void ath10k_sta_update_rx_duration(struct ath10k *ar, |
165 | struct ath10k_fw_stats *stats) | ||
161 | { | 166 | { |
162 | } | 167 | } |
163 | #endif /* CONFIG_MAC80211_DEBUGFS */ | 168 | #endif /* CONFIG_MAC80211_DEBUGFS */ |
diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c index 67ef75b60567..9955fea0802a 100644 --- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c | |||
@@ -18,13 +18,34 @@ | |||
18 | #include "wmi-ops.h" | 18 | #include "wmi-ops.h" |
19 | #include "debug.h" | 19 | #include "debug.h" |
20 | 20 | ||
21 | void ath10k_sta_update_rx_duration(struct ath10k *ar, struct list_head *head) | 21 | static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar, |
22 | { struct ieee80211_sta *sta; | 22 | struct ath10k_fw_stats *stats) |
23 | { | ||
24 | struct ath10k_fw_extd_stats_peer *peer; | ||
25 | struct ieee80211_sta *sta; | ||
26 | struct ath10k_sta *arsta; | ||
27 | |||
28 | rcu_read_lock(); | ||
29 | list_for_each_entry(peer, &stats->peers_extd, list) { | ||
30 | sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr, | ||
31 | NULL); | ||
32 | if (!sta) | ||
33 | continue; | ||
34 | arsta = (struct ath10k_sta *)sta->drv_priv; | ||
35 | arsta->rx_duration += (u64)peer->rx_duration; | ||
36 | } | ||
37 | rcu_read_unlock(); | ||
38 | } | ||
39 | |||
40 | static void ath10k_sta_update_stats_rx_duration(struct ath10k *ar, | ||
41 | struct ath10k_fw_stats *stats) | ||
42 | { | ||
23 | struct ath10k_fw_stats_peer *peer; | 43 | struct ath10k_fw_stats_peer *peer; |
44 | struct ieee80211_sta *sta; | ||
24 | struct ath10k_sta *arsta; | 45 | struct ath10k_sta *arsta; |
25 | 46 | ||
26 | rcu_read_lock(); | 47 | rcu_read_lock(); |
27 | list_for_each_entry(peer, head, list) { | 48 | list_for_each_entry(peer, &stats->peers, list) { |
28 | sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr, | 49 | sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr, |
29 | NULL); | 50 | NULL); |
30 | if (!sta) | 51 | if (!sta) |
@@ -35,6 +56,29 @@ void ath10k_sta_update_rx_duration(struct ath10k *ar, struct list_head *head) | |||
35 | rcu_read_unlock(); | 56 | rcu_read_unlock(); |
36 | } | 57 | } |
37 | 58 | ||
59 | void ath10k_sta_update_rx_duration(struct ath10k *ar, | ||
60 | struct ath10k_fw_stats *stats) | ||
61 | { | ||
62 | if (stats->extended) | ||
63 | ath10k_sta_update_extd_stats_rx_duration(ar, stats); | ||
64 | else | ||
65 | ath10k_sta_update_stats_rx_duration(ar, stats); | ||
66 | } | ||
67 | |||
68 | void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
69 | struct ieee80211_sta *sta, | ||
70 | struct station_info *sinfo) | ||
71 | { | ||
72 | struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; | ||
73 | struct ath10k *ar = arsta->arvif->ar; | ||
74 | |||
75 | if (!ath10k_peer_stats_enabled(ar)) | ||
76 | return; | ||
77 | |||
78 | sinfo->rx_duration = arsta->rx_duration; | ||
79 | sinfo->filled |= 1ULL << NL80211_STA_INFO_RX_DURATION; | ||
80 | } | ||
81 | |||
38 | static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file, | 82 | static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file, |
39 | char __user *user_buf, | 83 | char __user *user_buf, |
40 | size_t count, loff_t *ppos) | 84 | size_t count, loff_t *ppos) |
@@ -249,28 +293,6 @@ static const struct file_operations fops_delba = { | |||
249 | .llseek = default_llseek, | 293 | .llseek = default_llseek, |
250 | }; | 294 | }; |
251 | 295 | ||
252 | static ssize_t ath10k_dbg_sta_read_rx_duration(struct file *file, | ||
253 | char __user *user_buf, | ||
254 | size_t count, loff_t *ppos) | ||
255 | { | ||
256 | struct ieee80211_sta *sta = file->private_data; | ||
257 | struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; | ||
258 | char buf[100]; | ||
259 | int len = 0; | ||
260 | |||
261 | len = scnprintf(buf, sizeof(buf), | ||
262 | "%llu usecs\n", arsta->rx_duration); | ||
263 | |||
264 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
265 | } | ||
266 | |||
267 | static const struct file_operations fops_rx_duration = { | ||
268 | .read = ath10k_dbg_sta_read_rx_duration, | ||
269 | .open = simple_open, | ||
270 | .owner = THIS_MODULE, | ||
271 | .llseek = default_llseek, | ||
272 | }; | ||
273 | |||
274 | void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 296 | void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
275 | struct ieee80211_sta *sta, struct dentry *dir) | 297 | struct ieee80211_sta *sta, struct dentry *dir) |
276 | { | 298 | { |
@@ -279,6 +301,4 @@ void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
279 | debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba); | 301 | debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba); |
280 | debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp); | 302 | debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp); |
281 | debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba); | 303 | debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba); |
282 | debugfs_create_file("rx_duration", S_IRUGO, dir, sta, | ||
283 | &fops_rx_duration); | ||
284 | } | 304 | } |
diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h index cc827185d3e9..0c55cd92a951 100644 --- a/drivers/net/wireless/ath/ath10k/htc.h +++ b/drivers/net/wireless/ath/ath10k/htc.h | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | #include <linux/bug.h> | 23 | #include <linux/bug.h> |
24 | #include <linux/skbuff.h> | 24 | #include <linux/skbuff.h> |
25 | #include <linux/semaphore.h> | ||
26 | #include <linux/timer.h> | 25 | #include <linux/timer.h> |
27 | 26 | ||
28 | struct ath10k; | 27 | struct ath10k; |
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 80e645302b54..78db5d679f19 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | |||
@@ -748,7 +748,7 @@ ath10k_htt_rx_h_peer_channel(struct ath10k *ar, struct htt_rx_desc *rxd) | |||
748 | if (WARN_ON_ONCE(!arvif)) | 748 | if (WARN_ON_ONCE(!arvif)) |
749 | return NULL; | 749 | return NULL; |
750 | 750 | ||
751 | if (WARN_ON_ONCE(ath10k_mac_vif_chan(arvif->vif, &def))) | 751 | if (ath10k_mac_vif_chan(arvif->vif, &def)) |
752 | return NULL; | 752 | return NULL; |
753 | 753 | ||
754 | return def.chan; | 754 | return def.chan; |
@@ -2307,12 +2307,10 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) | |||
2307 | ath10k_htt_rx_delba(ar, resp); | 2307 | ath10k_htt_rx_delba(ar, resp); |
2308 | break; | 2308 | break; |
2309 | case HTT_T2H_MSG_TYPE_PKTLOG: { | 2309 | case HTT_T2H_MSG_TYPE_PKTLOG: { |
2310 | struct ath10k_pktlog_hdr *hdr = | ||
2311 | (struct ath10k_pktlog_hdr *)resp->pktlog_msg.payload; | ||
2312 | |||
2313 | trace_ath10k_htt_pktlog(ar, resp->pktlog_msg.payload, | 2310 | trace_ath10k_htt_pktlog(ar, resp->pktlog_msg.payload, |
2314 | sizeof(*hdr) + | 2311 | skb->len - |
2315 | __le16_to_cpu(hdr->size)); | 2312 | offsetof(struct htt_resp, |
2313 | pktlog_msg.payload)); | ||
2316 | break; | 2314 | break; |
2317 | } | 2315 | } |
2318 | case HTT_T2H_MSG_TYPE_RX_FLUSH: { | 2316 | case HTT_T2H_MSG_TYPE_RX_FLUSH: { |
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index 6269c610b0a3..7c072b605bc7 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c | |||
@@ -49,7 +49,7 @@ static void __ath10k_htt_tx_txq_recalc(struct ieee80211_hw *hw, | |||
49 | struct ieee80211_txq *txq) | 49 | struct ieee80211_txq *txq) |
50 | { | 50 | { |
51 | struct ath10k *ar = hw->priv; | 51 | struct ath10k *ar = hw->priv; |
52 | struct ath10k_sta *arsta = (void *)txq->sta->drv_priv; | 52 | struct ath10k_sta *arsta; |
53 | struct ath10k_vif *arvif = (void *)txq->vif->drv_priv; | 53 | struct ath10k_vif *arvif = (void *)txq->vif->drv_priv; |
54 | unsigned long frame_cnt; | 54 | unsigned long frame_cnt; |
55 | unsigned long byte_cnt; | 55 | unsigned long byte_cnt; |
@@ -67,10 +67,12 @@ static void __ath10k_htt_tx_txq_recalc(struct ieee80211_hw *hw, | |||
67 | if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH_PULL) | 67 | if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH_PULL) |
68 | return; | 68 | return; |
69 | 69 | ||
70 | if (txq->sta) | 70 | if (txq->sta) { |
71 | arsta = (void *)txq->sta->drv_priv; | ||
71 | peer_id = arsta->peer_id; | 72 | peer_id = arsta->peer_id; |
72 | else | 73 | } else { |
73 | peer_id = arvif->peer_id; | 74 | peer_id = arvif->peer_id; |
75 | } | ||
74 | 76 | ||
75 | tid = txq->tid; | 77 | tid = txq->tid; |
76 | bit = BIT(peer_id % 32); | 78 | bit = BIT(peer_id % 32); |
@@ -388,6 +390,8 @@ void ath10k_htt_tx_free(struct ath10k_htt *htt) | |||
388 | { | 390 | { |
389 | int size; | 391 | int size; |
390 | 392 | ||
393 | tasklet_kill(&htt->txrx_compl_task); | ||
394 | |||
391 | idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar); | 395 | idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar); |
392 | idr_destroy(&htt->pending_tx); | 396 | idr_destroy(&htt->pending_tx); |
393 | 397 | ||
@@ -733,16 +737,18 @@ static u8 ath10k_htt_tx_get_vdev_id(struct ath10k *ar, struct sk_buff *skb) | |||
733 | { | 737 | { |
734 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 738 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
735 | struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb); | 739 | struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb); |
736 | struct ath10k_vif *arvif = (void *)cb->vif->drv_priv; | 740 | struct ath10k_vif *arvif; |
737 | 741 | ||
738 | if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) | 742 | if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) { |
739 | return ar->scan.vdev_id; | 743 | return ar->scan.vdev_id; |
740 | else if (cb->vif) | 744 | } else if (cb->vif) { |
745 | arvif = (void *)cb->vif->drv_priv; | ||
741 | return arvif->vdev_id; | 746 | return arvif->vdev_id; |
742 | else if (ar->monitor_started) | 747 | } else if (ar->monitor_started) { |
743 | return ar->monitor_vdev_id; | 748 | return ar->monitor_vdev_id; |
744 | else | 749 | } else { |
745 | return 0; | 750 | return 0; |
751 | } | ||
746 | } | 752 | } |
747 | 753 | ||
748 | static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb, bool is_eth) | 754 | static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb, bool is_eth) |
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c index bd86e7a38db9..f903d468dbe6 100644 --- a/drivers/net/wireless/ath/ath10k/hw.c +++ b/drivers/net/wireless/ath/ath10k/hw.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include "hw.h" | 19 | #include "hw.h" |
20 | 20 | ||
21 | const struct ath10k_hw_regs qca988x_regs = { | 21 | const struct ath10k_hw_regs qca988x_regs = { |
22 | .rtc_state_cold_reset_mask = 0x00000400, | ||
23 | .rtc_soc_base_address = 0x00004000, | 22 | .rtc_soc_base_address = 0x00004000, |
24 | .rtc_wmac_base_address = 0x00005000, | 23 | .rtc_wmac_base_address = 0x00005000, |
25 | .soc_core_base_address = 0x00009000, | 24 | .soc_core_base_address = 0x00009000, |
@@ -46,7 +45,6 @@ const struct ath10k_hw_regs qca988x_regs = { | |||
46 | }; | 45 | }; |
47 | 46 | ||
48 | const struct ath10k_hw_regs qca6174_regs = { | 47 | const struct ath10k_hw_regs qca6174_regs = { |
49 | .rtc_state_cold_reset_mask = 0x00002000, | ||
50 | .rtc_soc_base_address = 0x00000800, | 48 | .rtc_soc_base_address = 0x00000800, |
51 | .rtc_wmac_base_address = 0x00001000, | 49 | .rtc_wmac_base_address = 0x00001000, |
52 | .soc_core_base_address = 0x0003a000, | 50 | .soc_core_base_address = 0x0003a000, |
@@ -73,7 +71,6 @@ const struct ath10k_hw_regs qca6174_regs = { | |||
73 | }; | 71 | }; |
74 | 72 | ||
75 | const struct ath10k_hw_regs qca99x0_regs = { | 73 | const struct ath10k_hw_regs qca99x0_regs = { |
76 | .rtc_state_cold_reset_mask = 0x00000400, | ||
77 | .rtc_soc_base_address = 0x00080000, | 74 | .rtc_soc_base_address = 0x00080000, |
78 | .rtc_wmac_base_address = 0x00000000, | 75 | .rtc_wmac_base_address = 0x00000000, |
79 | .soc_core_base_address = 0x00082000, | 76 | .soc_core_base_address = 0x00082000, |
@@ -168,6 +165,15 @@ const struct ath10k_hw_values qca99x0_values = { | |||
168 | .ce_desc_meta_data_lsb = 4, | 165 | .ce_desc_meta_data_lsb = 4, |
169 | }; | 166 | }; |
170 | 167 | ||
168 | const struct ath10k_hw_values qca9888_values = { | ||
169 | .rtc_state_val_on = 3, | ||
170 | .ce_count = 12, | ||
171 | .msi_assign_ce_max = 12, | ||
172 | .num_target_ce_config_wlan = 10, | ||
173 | .ce_desc_meta_data_mask = 0xFFF0, | ||
174 | .ce_desc_meta_data_lsb = 4, | ||
175 | }; | ||
176 | |||
171 | const struct ath10k_hw_values qca4019_values = { | 177 | const struct ath10k_hw_values qca4019_values = { |
172 | .ce_count = 12, | 178 | .ce_count = 12, |
173 | .num_target_ce_config_wlan = 10, | 179 | .num_target_ce_config_wlan = 10, |
@@ -198,7 +204,8 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey, | |||
198 | case ATH10K_HW_CC_WRAP_SHIFTED_EACH: | 204 | case ATH10K_HW_CC_WRAP_SHIFTED_EACH: |
199 | if (cc < cc_prev) | 205 | if (cc < cc_prev) |
200 | cc_fix = 0x7fffffff; | 206 | cc_fix = 0x7fffffff; |
201 | else | 207 | |
208 | if (rcc < rcc_prev) | ||
202 | rcc_fix = 0x7fffffff; | 209 | rcc_fix = 0x7fffffff; |
203 | break; | 210 | break; |
204 | case ATH10K_HW_CC_WRAP_DISABLED: | 211 | case ATH10K_HW_CC_WRAP_DISABLED: |
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index f31d3ce42470..e014cd732a0d 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #define QCA6164_2_1_DEVICE_ID (0x0041) | 26 | #define QCA6164_2_1_DEVICE_ID (0x0041) |
27 | #define QCA6174_2_1_DEVICE_ID (0x003e) | 27 | #define QCA6174_2_1_DEVICE_ID (0x003e) |
28 | #define QCA99X0_2_0_DEVICE_ID (0x0040) | 28 | #define QCA99X0_2_0_DEVICE_ID (0x0040) |
29 | #define QCA9888_2_0_DEVICE_ID (0x0056) | ||
29 | #define QCA9984_1_0_DEVICE_ID (0x0046) | 30 | #define QCA9984_1_0_DEVICE_ID (0x0046) |
30 | #define QCA9377_1_0_DEVICE_ID (0x0042) | 31 | #define QCA9377_1_0_DEVICE_ID (0x0042) |
31 | #define QCA9887_1_0_DEVICE_ID (0x0050) | 32 | #define QCA9887_1_0_DEVICE_ID (0x0050) |
@@ -108,6 +109,14 @@ enum qca9377_chip_id_rev { | |||
108 | #define QCA9984_HW_1_0_BOARD_DATA_FILE "board.bin" | 109 | #define QCA9984_HW_1_0_BOARD_DATA_FILE "board.bin" |
109 | #define QCA9984_HW_1_0_PATCH_LOAD_ADDR 0x1234 | 110 | #define QCA9984_HW_1_0_PATCH_LOAD_ADDR 0x1234 |
110 | 111 | ||
112 | /* QCA9888 2.0 defines */ | ||
113 | #define QCA9888_HW_2_0_DEV_VERSION 0x1000000 | ||
114 | #define QCA9888_HW_DEV_TYPE 0xc | ||
115 | #define QCA9888_HW_2_0_CHIP_ID_REV 0x0 | ||
116 | #define QCA9888_HW_2_0_FW_DIR ATH10K_FW_DIR "/QCA9888/hw2.0" | ||
117 | #define QCA9888_HW_2_0_BOARD_DATA_FILE "board.bin" | ||
118 | #define QCA9888_HW_2_0_PATCH_LOAD_ADDR 0x1234 | ||
119 | |||
111 | /* QCA9377 1.0 definitions */ | 120 | /* QCA9377 1.0 definitions */ |
112 | #define QCA9377_HW_1_0_FW_DIR ATH10K_FW_DIR "/QCA9377/hw1.0" | 121 | #define QCA9377_HW_1_0_FW_DIR ATH10K_FW_DIR "/QCA9377/hw1.0" |
113 | #define QCA9377_HW_1_0_BOARD_DATA_FILE "board.bin" | 122 | #define QCA9377_HW_1_0_BOARD_DATA_FILE "board.bin" |
@@ -210,6 +219,7 @@ enum ath10k_hw_rev { | |||
210 | ATH10K_HW_QCA988X, | 219 | ATH10K_HW_QCA988X, |
211 | ATH10K_HW_QCA6174, | 220 | ATH10K_HW_QCA6174, |
212 | ATH10K_HW_QCA99X0, | 221 | ATH10K_HW_QCA99X0, |
222 | ATH10K_HW_QCA9888, | ||
213 | ATH10K_HW_QCA9984, | 223 | ATH10K_HW_QCA9984, |
214 | ATH10K_HW_QCA9377, | 224 | ATH10K_HW_QCA9377, |
215 | ATH10K_HW_QCA4019, | 225 | ATH10K_HW_QCA4019, |
@@ -217,7 +227,6 @@ enum ath10k_hw_rev { | |||
217 | }; | 227 | }; |
218 | 228 | ||
219 | struct ath10k_hw_regs { | 229 | struct ath10k_hw_regs { |
220 | u32 rtc_state_cold_reset_mask; | ||
221 | u32 rtc_soc_base_address; | 230 | u32 rtc_soc_base_address; |
222 | u32 rtc_wmac_base_address; | 231 | u32 rtc_wmac_base_address; |
223 | u32 soc_core_base_address; | 232 | u32 soc_core_base_address; |
@@ -260,6 +269,7 @@ struct ath10k_hw_values { | |||
260 | extern const struct ath10k_hw_values qca988x_values; | 269 | extern const struct ath10k_hw_values qca988x_values; |
261 | extern const struct ath10k_hw_values qca6174_values; | 270 | extern const struct ath10k_hw_values qca6174_values; |
262 | extern const struct ath10k_hw_values qca99x0_values; | 271 | extern const struct ath10k_hw_values qca99x0_values; |
272 | extern const struct ath10k_hw_values qca9888_values; | ||
263 | extern const struct ath10k_hw_values qca4019_values; | 273 | extern const struct ath10k_hw_values qca4019_values; |
264 | 274 | ||
265 | void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey, | 275 | void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey, |
@@ -269,6 +279,7 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey, | |||
269 | #define QCA_REV_9887(ar) ((ar)->hw_rev == ATH10K_HW_QCA9887) | 279 | #define QCA_REV_9887(ar) ((ar)->hw_rev == ATH10K_HW_QCA9887) |
270 | #define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174) | 280 | #define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174) |
271 | #define QCA_REV_99X0(ar) ((ar)->hw_rev == ATH10K_HW_QCA99X0) | 281 | #define QCA_REV_99X0(ar) ((ar)->hw_rev == ATH10K_HW_QCA99X0) |
282 | #define QCA_REV_9888(ar) ((ar)->hw_rev == ATH10K_HW_QCA9888) | ||
272 | #define QCA_REV_9984(ar) ((ar)->hw_rev == ATH10K_HW_QCA9984) | 283 | #define QCA_REV_9984(ar) ((ar)->hw_rev == ATH10K_HW_QCA9984) |
273 | #define QCA_REV_9377(ar) ((ar)->hw_rev == ATH10K_HW_QCA9377) | 284 | #define QCA_REV_9377(ar) ((ar)->hw_rev == ATH10K_HW_QCA9377) |
274 | #define QCA_REV_40XX(ar) ((ar)->hw_rev == ATH10K_HW_QCA4019) | 285 | #define QCA_REV_40XX(ar) ((ar)->hw_rev == ATH10K_HW_QCA4019) |
@@ -296,25 +307,6 @@ enum ath10k_mcast2ucast_mode { | |||
296 | ATH10K_MCAST2UCAST_ENABLED = 1, | 307 | ATH10K_MCAST2UCAST_ENABLED = 1, |
297 | }; | 308 | }; |
298 | 309 | ||
299 | struct ath10k_pktlog_hdr { | ||
300 | __le16 flags; | ||
301 | __le16 missed_cnt; | ||
302 | __le16 log_type; | ||
303 | __le16 size; | ||
304 | __le32 timestamp; | ||
305 | u8 payload[0]; | ||
306 | } __packed; | ||
307 | |||
308 | struct ath10k_pktlog_10_4_hdr { | ||
309 | __le16 flags; | ||
310 | __le16 missed_cnt; | ||
311 | __le16 log_type; | ||
312 | __le16 size; | ||
313 | __le32 timestamp; | ||
314 | __le32 type_specific_data; | ||
315 | u8 payload[0]; | ||
316 | } __packed; | ||
317 | |||
318 | enum ath10k_hw_rate_ofdm { | 310 | enum ath10k_hw_rate_ofdm { |
319 | ATH10K_HW_RATE_OFDM_48M = 0, | 311 | ATH10K_HW_RATE_OFDM_48M = 0, |
320 | ATH10K_HW_RATE_OFDM_24M, | 312 | ATH10K_HW_RATE_OFDM_24M, |
@@ -535,7 +527,6 @@ enum ath10k_hw_cc_wraparound_type { | |||
535 | /* as of IP3.7.1 */ | 527 | /* as of IP3.7.1 */ |
536 | #define RTC_STATE_V_ON ar->hw_values->rtc_state_val_on | 528 | #define RTC_STATE_V_ON ar->hw_values->rtc_state_val_on |
537 | 529 | ||
538 | #define RTC_STATE_COLD_RESET_MASK ar->regs->rtc_state_cold_reset_mask | ||
539 | #define RTC_STATE_V_LSB 0 | 530 | #define RTC_STATE_V_LSB 0 |
540 | #define RTC_STATE_V_MASK 0x00000007 | 531 | #define RTC_STATE_V_MASK 0x00000007 |
541 | #define RTC_STATE_ADDRESS 0x0000 | 532 | #define RTC_STATE_ADDRESS 0x0000 |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index ebc12c521fe0..fb8e38df9446 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -802,6 +802,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) | |||
802 | { | 802 | { |
803 | struct ath10k_peer *peer, *tmp; | 803 | struct ath10k_peer *peer, *tmp; |
804 | int peer_id; | 804 | int peer_id; |
805 | int i; | ||
805 | 806 | ||
806 | lockdep_assert_held(&ar->conf_mutex); | 807 | lockdep_assert_held(&ar->conf_mutex); |
807 | 808 | ||
@@ -818,6 +819,17 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) | |||
818 | ar->peer_map[peer_id] = NULL; | 819 | ar->peer_map[peer_id] = NULL; |
819 | } | 820 | } |
820 | 821 | ||
822 | /* Double check that peer is properly un-referenced from | ||
823 | * the peer_map | ||
824 | */ | ||
825 | for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) { | ||
826 | if (ar->peer_map[i] == peer) { | ||
827 | ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %p idx %d)\n", | ||
828 | peer->addr, peer, i); | ||
829 | ar->peer_map[i] = NULL; | ||
830 | } | ||
831 | } | ||
832 | |||
821 | list_del(&peer->list); | 833 | list_del(&peer->list); |
822 | kfree(peer); | 834 | kfree(peer); |
823 | ar->num_peers--; | 835 | ar->num_peers--; |
@@ -828,6 +840,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) | |||
828 | static void ath10k_peer_cleanup_all(struct ath10k *ar) | 840 | static void ath10k_peer_cleanup_all(struct ath10k *ar) |
829 | { | 841 | { |
830 | struct ath10k_peer *peer, *tmp; | 842 | struct ath10k_peer *peer, *tmp; |
843 | int i; | ||
831 | 844 | ||
832 | lockdep_assert_held(&ar->conf_mutex); | 845 | lockdep_assert_held(&ar->conf_mutex); |
833 | 846 | ||
@@ -836,6 +849,10 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar) | |||
836 | list_del(&peer->list); | 849 | list_del(&peer->list); |
837 | kfree(peer); | 850 | kfree(peer); |
838 | } | 851 | } |
852 | |||
853 | for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) | ||
854 | ar->peer_map[i] = NULL; | ||
855 | |||
839 | spin_unlock_bh(&ar->data_lock); | 856 | spin_unlock_bh(&ar->data_lock); |
840 | 857 | ||
841 | ar->num_peers = 0; | 858 | ar->num_peers = 0; |
@@ -2939,7 +2956,7 @@ static int ath10k_update_channel_list(struct ath10k *ar) | |||
2939 | if (channel->flags & IEEE80211_CHAN_DISABLED) | 2956 | if (channel->flags & IEEE80211_CHAN_DISABLED) |
2940 | continue; | 2957 | continue; |
2941 | 2958 | ||
2942 | ch->allow_ht = true; | 2959 | ch->allow_ht = true; |
2943 | 2960 | ||
2944 | /* FIXME: when should we really allow VHT? */ | 2961 | /* FIXME: when should we really allow VHT? */ |
2945 | ch->allow_vht = true; | 2962 | ch->allow_vht = true; |
@@ -3675,17 +3692,18 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work) | |||
3675 | 3692 | ||
3676 | static void ath10k_mac_txq_init(struct ieee80211_txq *txq) | 3693 | static void ath10k_mac_txq_init(struct ieee80211_txq *txq) |
3677 | { | 3694 | { |
3678 | struct ath10k_txq *artxq = (void *)txq->drv_priv; | 3695 | struct ath10k_txq *artxq; |
3679 | 3696 | ||
3680 | if (!txq) | 3697 | if (!txq) |
3681 | return; | 3698 | return; |
3682 | 3699 | ||
3700 | artxq = (void *)txq->drv_priv; | ||
3683 | INIT_LIST_HEAD(&artxq->list); | 3701 | INIT_LIST_HEAD(&artxq->list); |
3684 | } | 3702 | } |
3685 | 3703 | ||
3686 | static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq) | 3704 | static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq) |
3687 | { | 3705 | { |
3688 | struct ath10k_txq *artxq = (void *)txq->drv_priv; | 3706 | struct ath10k_txq *artxq; |
3689 | struct ath10k_skb_cb *cb; | 3707 | struct ath10k_skb_cb *cb; |
3690 | struct sk_buff *msdu; | 3708 | struct sk_buff *msdu; |
3691 | int msdu_id; | 3709 | int msdu_id; |
@@ -3693,6 +3711,7 @@ static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq) | |||
3693 | if (!txq) | 3711 | if (!txq) |
3694 | return; | 3712 | return; |
3695 | 3713 | ||
3714 | artxq = (void *)txq->drv_priv; | ||
3696 | spin_lock_bh(&ar->txqs_lock); | 3715 | spin_lock_bh(&ar->txqs_lock); |
3697 | if (!list_empty(&artxq->list)) | 3716 | if (!list_empty(&artxq->list)) |
3698 | list_del_init(&artxq->list); | 3717 | list_del_init(&artxq->list); |
@@ -4228,6 +4247,9 @@ static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar) | |||
4228 | mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); | 4247 | mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); |
4229 | } | 4248 | } |
4230 | 4249 | ||
4250 | if (ar->cfg_tx_chainmask <= 1) | ||
4251 | vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC; | ||
4252 | |||
4231 | vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); | 4253 | vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); |
4232 | vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); | 4254 | vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); |
4233 | 4255 | ||
@@ -4265,7 +4287,7 @@ static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar) | |||
4265 | ht_cap.cap |= smps; | 4287 | ht_cap.cap |= smps; |
4266 | } | 4288 | } |
4267 | 4289 | ||
4268 | if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC) | 4290 | if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1)) |
4269 | ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; | 4291 | ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; |
4270 | 4292 | ||
4271 | if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) { | 4293 | if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) { |
@@ -5979,9 +6001,17 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, | |||
5979 | continue; | 6001 | continue; |
5980 | 6002 | ||
5981 | if (peer->sta == sta) { | 6003 | if (peer->sta == sta) { |
5982 | ath10k_warn(ar, "found sta peer %pM entry on vdev %i after it was supposedly removed\n", | 6004 | ath10k_warn(ar, "found sta peer %pM (ptr %p id %d) entry on vdev %i after it was supposedly removed\n", |
5983 | sta->addr, arvif->vdev_id); | 6005 | sta->addr, peer, i, arvif->vdev_id); |
5984 | peer->sta = NULL; | 6006 | peer->sta = NULL; |
6007 | |||
6008 | /* Clean up the peer object as well since we | ||
6009 | * must have failed to do this above. | ||
6010 | */ | ||
6011 | list_del(&peer->list); | ||
6012 | ar->peer_map[i] = NULL; | ||
6013 | kfree(peer); | ||
6014 | ar->num_peers--; | ||
5985 | } | 6015 | } |
5986 | } | 6016 | } |
5987 | spin_unlock_bh(&ar->data_lock); | 6017 | spin_unlock_bh(&ar->data_lock); |
@@ -7406,6 +7436,7 @@ static const struct ieee80211_ops ath10k_ops = { | |||
7406 | #endif | 7436 | #endif |
7407 | #ifdef CONFIG_MAC80211_DEBUGFS | 7437 | #ifdef CONFIG_MAC80211_DEBUGFS |
7408 | .sta_add_debugfs = ath10k_sta_add_debugfs, | 7438 | .sta_add_debugfs = ath10k_sta_add_debugfs, |
7439 | .sta_statistics = ath10k_sta_statistics, | ||
7409 | #endif | 7440 | #endif |
7410 | }; | 7441 | }; |
7411 | 7442 | ||
@@ -7475,21 +7506,32 @@ static const struct ieee80211_channel ath10k_5ghz_channels[] = { | |||
7475 | struct ath10k *ath10k_mac_create(size_t priv_size) | 7506 | struct ath10k *ath10k_mac_create(size_t priv_size) |
7476 | { | 7507 | { |
7477 | struct ieee80211_hw *hw; | 7508 | struct ieee80211_hw *hw; |
7509 | struct ieee80211_ops *ops; | ||
7478 | struct ath10k *ar; | 7510 | struct ath10k *ar; |
7479 | 7511 | ||
7480 | hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops); | 7512 | ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL); |
7481 | if (!hw) | 7513 | if (!ops) |
7482 | return NULL; | 7514 | return NULL; |
7483 | 7515 | ||
7516 | hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops); | ||
7517 | if (!hw) { | ||
7518 | kfree(ops); | ||
7519 | return NULL; | ||
7520 | } | ||
7521 | |||
7484 | ar = hw->priv; | 7522 | ar = hw->priv; |
7485 | ar->hw = hw; | 7523 | ar->hw = hw; |
7524 | ar->ops = ops; | ||
7486 | 7525 | ||
7487 | return ar; | 7526 | return ar; |
7488 | } | 7527 | } |
7489 | 7528 | ||
7490 | void ath10k_mac_destroy(struct ath10k *ar) | 7529 | void ath10k_mac_destroy(struct ath10k *ar) |
7491 | { | 7530 | { |
7531 | struct ieee80211_ops *ops = ar->ops; | ||
7532 | |||
7492 | ieee80211_free_hw(ar->hw); | 7533 | ieee80211_free_hw(ar->hw); |
7534 | kfree(ops); | ||
7493 | } | 7535 | } |
7494 | 7536 | ||
7495 | static const struct ieee80211_iface_limit ath10k_if_limits[] = { | 7537 | static const struct ieee80211_iface_limit ath10k_if_limits[] = { |
@@ -7923,6 +7965,15 @@ int ath10k_mac_register(struct ath10k *ar) | |||
7923 | ath10k_warn(ar, "failed to initialise DFS pattern detector\n"); | 7965 | ath10k_warn(ar, "failed to initialise DFS pattern detector\n"); |
7924 | } | 7966 | } |
7925 | 7967 | ||
7968 | /* Current wake_tx_queue implementation imposes a significant | ||
7969 | * performance penalty in some setups. The tx scheduling code needs | ||
7970 | * more work anyway so disable the wake_tx_queue unless firmware | ||
7971 | * supports the pull-push mechanism. | ||
7972 | */ | ||
7973 | if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL, | ||
7974 | ar->running_fw->fw_file.fw_features)) | ||
7975 | ar->ops->wake_tx_queue = NULL; | ||
7976 | |||
7926 | ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy, | 7977 | ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy, |
7927 | ath10k_reg_notifier); | 7978 | ath10k_reg_notifier); |
7928 | if (ret) { | 7979 | if (ret) { |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index f06dd3941bac..9a22c478dd1b 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
@@ -56,6 +56,7 @@ static const struct pci_device_id ath10k_pci_id_table[] = { | |||
56 | { PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */ | 56 | { PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */ |
57 | { PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */ | 57 | { PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */ |
58 | { PCI_VDEVICE(ATHEROS, QCA99X0_2_0_DEVICE_ID) }, /* PCI-E QCA99X0 V2 */ | 58 | { PCI_VDEVICE(ATHEROS, QCA99X0_2_0_DEVICE_ID) }, /* PCI-E QCA99X0 V2 */ |
59 | { PCI_VDEVICE(ATHEROS, QCA9888_2_0_DEVICE_ID) }, /* PCI-E QCA9888 V2 */ | ||
59 | { PCI_VDEVICE(ATHEROS, QCA9984_1_0_DEVICE_ID) }, /* PCI-E QCA9984 V1 */ | 60 | { PCI_VDEVICE(ATHEROS, QCA9984_1_0_DEVICE_ID) }, /* PCI-E QCA9984 V1 */ |
60 | { PCI_VDEVICE(ATHEROS, QCA9377_1_0_DEVICE_ID) }, /* PCI-E QCA9377 V1 */ | 61 | { PCI_VDEVICE(ATHEROS, QCA9377_1_0_DEVICE_ID) }, /* PCI-E QCA9377 V1 */ |
61 | { PCI_VDEVICE(ATHEROS, QCA9887_1_0_DEVICE_ID) }, /* PCI-E QCA9887 */ | 62 | { PCI_VDEVICE(ATHEROS, QCA9887_1_0_DEVICE_ID) }, /* PCI-E QCA9887 */ |
@@ -85,6 +86,8 @@ static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = { | |||
85 | 86 | ||
86 | { QCA9984_1_0_DEVICE_ID, QCA9984_HW_1_0_CHIP_ID_REV }, | 87 | { QCA9984_1_0_DEVICE_ID, QCA9984_HW_1_0_CHIP_ID_REV }, |
87 | 88 | ||
89 | { QCA9888_2_0_DEVICE_ID, QCA9888_HW_2_0_CHIP_ID_REV }, | ||
90 | |||
88 | { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_0_CHIP_ID_REV }, | 91 | { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_0_CHIP_ID_REV }, |
89 | { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_1_CHIP_ID_REV }, | 92 | { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_1_CHIP_ID_REV }, |
90 | 93 | ||
@@ -850,6 +853,7 @@ static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) | |||
850 | CORE_CTRL_ADDRESS) & | 853 | CORE_CTRL_ADDRESS) & |
851 | 0x7ff) << 21; | 854 | 0x7ff) << 21; |
852 | break; | 855 | break; |
856 | case ATH10K_HW_QCA9888: | ||
853 | case ATH10K_HW_QCA99X0: | 857 | case ATH10K_HW_QCA99X0: |
854 | case ATH10K_HW_QCA9984: | 858 | case ATH10K_HW_QCA9984: |
855 | case ATH10K_HW_QCA4019: | 859 | case ATH10K_HW_QCA4019: |
@@ -1583,6 +1587,7 @@ static void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar) | |||
1583 | break; | 1587 | break; |
1584 | case ATH10K_HW_QCA99X0: | 1588 | case ATH10K_HW_QCA99X0: |
1585 | case ATH10K_HW_QCA9984: | 1589 | case ATH10K_HW_QCA9984: |
1590 | case ATH10K_HW_QCA9888: | ||
1586 | case ATH10K_HW_QCA4019: | 1591 | case ATH10K_HW_QCA4019: |
1587 | /* TODO: Find appropriate register configuration for QCA99X0 | 1592 | /* TODO: Find appropriate register configuration for QCA99X0 |
1588 | * to mask irq/MSI. | 1593 | * to mask irq/MSI. |
@@ -1608,6 +1613,7 @@ static void ath10k_pci_irq_msi_fw_unmask(struct ath10k *ar) | |||
1608 | break; | 1613 | break; |
1609 | case ATH10K_HW_QCA99X0: | 1614 | case ATH10K_HW_QCA99X0: |
1610 | case ATH10K_HW_QCA9984: | 1615 | case ATH10K_HW_QCA9984: |
1616 | case ATH10K_HW_QCA9888: | ||
1611 | case ATH10K_HW_QCA4019: | 1617 | case ATH10K_HW_QCA4019: |
1612 | /* TODO: Find appropriate register configuration for QCA99X0 | 1618 | /* TODO: Find appropriate register configuration for QCA99X0 |
1613 | * to unmask irq/MSI. | 1619 | * to unmask irq/MSI. |
@@ -1948,6 +1954,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar) | |||
1948 | switch (ar_pci->pdev->device) { | 1954 | switch (ar_pci->pdev->device) { |
1949 | case QCA988X_2_0_DEVICE_ID: | 1955 | case QCA988X_2_0_DEVICE_ID: |
1950 | case QCA99X0_2_0_DEVICE_ID: | 1956 | case QCA99X0_2_0_DEVICE_ID: |
1957 | case QCA9888_2_0_DEVICE_ID: | ||
1951 | case QCA9984_1_0_DEVICE_ID: | 1958 | case QCA9984_1_0_DEVICE_ID: |
1952 | case QCA9887_1_0_DEVICE_ID: | 1959 | case QCA9887_1_0_DEVICE_ID: |
1953 | return 1; | 1960 | return 1; |
@@ -2216,6 +2223,14 @@ static void ath10k_pci_fw_crashed_clear(struct ath10k *ar) | |||
2216 | ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, val); | 2223 | ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, val); |
2217 | } | 2224 | } |
2218 | 2225 | ||
2226 | static bool ath10k_pci_has_device_gone(struct ath10k *ar) | ||
2227 | { | ||
2228 | u32 val; | ||
2229 | |||
2230 | val = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); | ||
2231 | return (val == 0xffffffff); | ||
2232 | } | ||
2233 | |||
2219 | /* this function effectively clears target memory controller assert line */ | 2234 | /* this function effectively clears target memory controller assert line */ |
2220 | static void ath10k_pci_warm_reset_si0(struct ath10k *ar) | 2235 | static void ath10k_pci_warm_reset_si0(struct ath10k *ar) |
2221 | { | 2236 | { |
@@ -2748,6 +2763,9 @@ static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg) | |||
2748 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | 2763 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
2749 | int ret; | 2764 | int ret; |
2750 | 2765 | ||
2766 | if (ath10k_pci_has_device_gone(ar)) | ||
2767 | return IRQ_NONE; | ||
2768 | |||
2751 | ret = ath10k_pci_force_wake(ar); | 2769 | ret = ath10k_pci_force_wake(ar); |
2752 | if (ret) { | 2770 | if (ret) { |
2753 | ath10k_warn(ar, "failed to wake device up on irq: %d\n", ret); | 2771 | ath10k_warn(ar, "failed to wake device up on irq: %d\n", ret); |
@@ -3169,6 +3187,12 @@ static int ath10k_pci_probe(struct pci_dev *pdev, | |||
3169 | pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset; | 3187 | pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset; |
3170 | pci_hard_reset = ath10k_pci_qca99x0_chip_reset; | 3188 | pci_hard_reset = ath10k_pci_qca99x0_chip_reset; |
3171 | break; | 3189 | break; |
3190 | case QCA9888_2_0_DEVICE_ID: | ||
3191 | hw_rev = ATH10K_HW_QCA9888; | ||
3192 | pci_ps = false; | ||
3193 | pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset; | ||
3194 | pci_hard_reset = ath10k_pci_qca99x0_chip_reset; | ||
3195 | break; | ||
3172 | case QCA9377_1_0_DEVICE_ID: | 3196 | case QCA9377_1_0_DEVICE_ID: |
3173 | hw_rev = ATH10K_HW_QCA9377; | 3197 | hw_rev = ATH10K_HW_QCA9377; |
3174 | pci_ps = true; | 3198 | pci_ps = true; |
diff --git a/drivers/net/wireless/ath/ath10k/spectral.c b/drivers/net/wireless/ath/ath10k/spectral.c index 4671cfbcd8f7..7d9b0da1b010 100644 --- a/drivers/net/wireless/ath/ath10k/spectral.c +++ b/drivers/net/wireless/ath/ath10k/spectral.c | |||
@@ -101,9 +101,9 @@ int ath10k_spectral_process_fft(struct ath10k *ar, | |||
101 | break; | 101 | break; |
102 | case 80: | 102 | case 80: |
103 | /* TODO: As experiments with an analogue sender and various | 103 | /* TODO: As experiments with an analogue sender and various |
104 | * configuaritions (fft-sizes of 64/128/256 and 20/40/80 Mhz) | 104 | * configurations (fft-sizes of 64/128/256 and 20/40/80 Mhz) |
105 | * show, the particular configuration of 80 MHz/64 bins does | 105 | * show, the particular configuration of 80 MHz/64 bins does |
106 | * not match with the other smaples at all. Until the reason | 106 | * not match with the other samples at all. Until the reason |
107 | * for that is found, don't report these samples. | 107 | * for that is found, don't report these samples. |
108 | */ | 108 | */ |
109 | if (bin_len == 64) | 109 | if (bin_len == 64) |
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c index 1966c787998b..b29a86a26c13 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.c +++ b/drivers/net/wireless/ath/ath10k/txrx.c | |||
@@ -81,10 +81,11 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, | |||
81 | 81 | ||
82 | skb_cb = ATH10K_SKB_CB(msdu); | 82 | skb_cb = ATH10K_SKB_CB(msdu); |
83 | txq = skb_cb->txq; | 83 | txq = skb_cb->txq; |
84 | artxq = (void *)txq->drv_priv; | ||
85 | 84 | ||
86 | if (txq) | 85 | if (txq) { |
86 | artxq = (void *)txq->drv_priv; | ||
87 | artxq->num_fw_queued--; | 87 | artxq->num_fw_queued--; |
88 | } | ||
88 | 89 | ||
89 | ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id); | 90 | ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id); |
90 | ath10k_htt_tx_dec_pending(htt); | 91 | ath10k_htt_tx_dec_pending(htt); |
@@ -216,6 +217,7 @@ void ath10k_peer_map_event(struct ath10k_htt *htt, | |||
216 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt peer map vdev %d peer %pM id %d\n", | 217 | ath10k_dbg(ar, ATH10K_DBG_HTT, "htt peer map vdev %d peer %pM id %d\n", |
217 | ev->vdev_id, ev->addr, ev->peer_id); | 218 | ev->vdev_id, ev->addr, ev->peer_id); |
218 | 219 | ||
220 | WARN_ON(ar->peer_map[ev->peer_id] && (ar->peer_map[ev->peer_id] != peer)); | ||
219 | ar->peer_map[ev->peer_id] = peer; | 221 | ar->peer_map[ev->peer_id] = peer; |
220 | set_bit(ev->peer_id, peer->peer_ids); | 222 | set_bit(ev->peer_id, peer->peer_ids); |
221 | exit: | 223 | exit: |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 6279ab4a760e..169cd2e783eb 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -1826,7 +1826,7 @@ static struct sk_buff * | |||
1826 | ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) | 1826 | ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) |
1827 | { | 1827 | { |
1828 | struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); | 1828 | struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); |
1829 | struct ath10k_vif *arvif = (void *)cb->vif->drv_priv; | 1829 | struct ath10k_vif *arvif; |
1830 | struct wmi_mgmt_tx_cmd *cmd; | 1830 | struct wmi_mgmt_tx_cmd *cmd; |
1831 | struct ieee80211_hdr *hdr; | 1831 | struct ieee80211_hdr *hdr; |
1832 | struct sk_buff *skb; | 1832 | struct sk_buff *skb; |
@@ -1838,10 +1838,12 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) | |||
1838 | hdr = (struct ieee80211_hdr *)msdu->data; | 1838 | hdr = (struct ieee80211_hdr *)msdu->data; |
1839 | fc = le16_to_cpu(hdr->frame_control); | 1839 | fc = le16_to_cpu(hdr->frame_control); |
1840 | 1840 | ||
1841 | if (cb->vif) | 1841 | if (cb->vif) { |
1842 | arvif = (void *)cb->vif->drv_priv; | ||
1842 | vdev_id = arvif->vdev_id; | 1843 | vdev_id = arvif->vdev_id; |
1843 | else | 1844 | } else { |
1844 | vdev_id = 0; | 1845 | vdev_id = 0; |
1846 | } | ||
1845 | 1847 | ||
1846 | if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control))) | 1848 | if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control))) |
1847 | return ERR_PTR(-EINVAL); | 1849 | return ERR_PTR(-EINVAL); |
@@ -2924,6 +2926,7 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar, | |||
2924 | u32 num_pdev_ext_stats; | 2926 | u32 num_pdev_ext_stats; |
2925 | u32 num_vdev_stats; | 2927 | u32 num_vdev_stats; |
2926 | u32 num_peer_stats; | 2928 | u32 num_peer_stats; |
2929 | u32 num_bcnflt_stats; | ||
2927 | u32 stats_id; | 2930 | u32 stats_id; |
2928 | int i; | 2931 | int i; |
2929 | 2932 | ||
@@ -2934,6 +2937,7 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar, | |||
2934 | num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats); | 2937 | num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats); |
2935 | num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); | 2938 | num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); |
2936 | num_peer_stats = __le32_to_cpu(ev->num_peer_stats); | 2939 | num_peer_stats = __le32_to_cpu(ev->num_peer_stats); |
2940 | num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats); | ||
2937 | stats_id = __le32_to_cpu(ev->stats_id); | 2941 | stats_id = __le32_to_cpu(ev->stats_id); |
2938 | 2942 | ||
2939 | for (i = 0; i < num_pdev_stats; i++) { | 2943 | for (i = 0; i < num_pdev_stats; i++) { |
@@ -2974,32 +2978,57 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar, | |||
2974 | /* fw doesn't implement vdev stats */ | 2978 | /* fw doesn't implement vdev stats */ |
2975 | 2979 | ||
2976 | for (i = 0; i < num_peer_stats; i++) { | 2980 | for (i = 0; i < num_peer_stats; i++) { |
2977 | const struct wmi_10_4_peer_extd_stats *src; | 2981 | const struct wmi_10_4_peer_stats *src; |
2978 | struct ath10k_fw_stats_peer *dst; | 2982 | struct ath10k_fw_stats_peer *dst; |
2979 | int stats_len; | ||
2980 | bool extd_peer_stats = !!(stats_id & WMI_10_4_STAT_PEER_EXTD); | ||
2981 | |||
2982 | if (extd_peer_stats) | ||
2983 | stats_len = sizeof(struct wmi_10_4_peer_extd_stats); | ||
2984 | else | ||
2985 | stats_len = sizeof(struct wmi_10_4_peer_stats); | ||
2986 | 2983 | ||
2987 | src = (void *)skb->data; | 2984 | src = (void *)skb->data; |
2988 | if (!skb_pull(skb, stats_len)) | 2985 | if (!skb_pull(skb, sizeof(*src))) |
2989 | return -EPROTO; | 2986 | return -EPROTO; |
2990 | 2987 | ||
2991 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | 2988 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); |
2992 | if (!dst) | 2989 | if (!dst) |
2993 | continue; | 2990 | continue; |
2994 | 2991 | ||
2995 | ath10k_wmi_10_4_pull_peer_stats(&src->common, dst); | 2992 | ath10k_wmi_10_4_pull_peer_stats(src, dst); |
2996 | /* FIXME: expose 10.4 specific values */ | ||
2997 | if (extd_peer_stats) | ||
2998 | dst->rx_duration = __le32_to_cpu(src->rx_duration); | ||
2999 | |||
3000 | list_add_tail(&dst->list, &stats->peers); | 2993 | list_add_tail(&dst->list, &stats->peers); |
3001 | } | 2994 | } |
3002 | 2995 | ||
2996 | for (i = 0; i < num_bcnflt_stats; i++) { | ||
2997 | const struct wmi_10_4_bss_bcn_filter_stats *src; | ||
2998 | |||
2999 | src = (void *)skb->data; | ||
3000 | if (!skb_pull(skb, sizeof(*src))) | ||
3001 | return -EPROTO; | ||
3002 | |||
3003 | /* FIXME: expose values to userspace | ||
3004 | * | ||
3005 | * Note: Even though this loop seems to do nothing it is | ||
3006 | * required to parse following sub-structures properly. | ||
3007 | */ | ||
3008 | } | ||
3009 | |||
3010 | if ((stats_id & WMI_10_4_STAT_PEER_EXTD) == 0) | ||
3011 | return 0; | ||
3012 | |||
3013 | stats->extended = true; | ||
3014 | |||
3015 | for (i = 0; i < num_peer_stats; i++) { | ||
3016 | const struct wmi_10_4_peer_extd_stats *src; | ||
3017 | struct ath10k_fw_extd_stats_peer *dst; | ||
3018 | |||
3019 | src = (void *)skb->data; | ||
3020 | if (!skb_pull(skb, sizeof(*src))) | ||
3021 | return -EPROTO; | ||
3022 | |||
3023 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | ||
3024 | if (!dst) | ||
3025 | continue; | ||
3026 | |||
3027 | ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr); | ||
3028 | dst->rx_duration = __le32_to_cpu(src->rx_duration); | ||
3029 | list_add_tail(&dst->list, &stats->peers_extd); | ||
3030 | } | ||
3031 | |||
3003 | return 0; | 3032 | return 0; |
3004 | } | 3033 | } |
3005 | 3034 | ||
@@ -5257,6 +5286,9 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5257 | case WMI_10_4_PEER_STA_KICKOUT_EVENTID: | 5286 | case WMI_10_4_PEER_STA_KICKOUT_EVENTID: |
5258 | ath10k_wmi_event_peer_sta_kickout(ar, skb); | 5287 | ath10k_wmi_event_peer_sta_kickout(ar, skb); |
5259 | break; | 5288 | break; |
5289 | case WMI_10_4_ROAM_EVENTID: | ||
5290 | ath10k_wmi_event_roam(ar, skb); | ||
5291 | break; | ||
5260 | case WMI_10_4_HOST_SWBA_EVENTID: | 5292 | case WMI_10_4_HOST_SWBA_EVENTID: |
5261 | ath10k_wmi_event_host_swba(ar, skb); | 5293 | ath10k_wmi_event_host_swba(ar, skb); |
5262 | break; | 5294 | break; |
@@ -7903,6 +7935,7 @@ static const struct wmi_ops wmi_10_4_ops = { | |||
7903 | .pull_phyerr = ath10k_wmi_10_4_op_pull_phyerr_ev, | 7935 | .pull_phyerr = ath10k_wmi_10_4_op_pull_phyerr_ev, |
7904 | .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev, | 7936 | .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev, |
7905 | .pull_rdy = ath10k_wmi_op_pull_rdy_ev, | 7937 | .pull_rdy = ath10k_wmi_op_pull_rdy_ev, |
7938 | .pull_roam_ev = ath10k_wmi_op_pull_roam_ev, | ||
7906 | .get_txbf_conf_scheme = ath10k_wmi_10_4_txbf_conf_scheme, | 7939 | .get_txbf_conf_scheme = ath10k_wmi_10_4_txbf_conf_scheme, |
7907 | 7940 | ||
7908 | .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, | 7941 | .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 90f594e89f94..3ef468893b3f 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h | |||
@@ -4340,7 +4340,6 @@ struct wmi_10_4_peer_stats { | |||
4340 | } __packed; | 4340 | } __packed; |
4341 | 4341 | ||
4342 | struct wmi_10_4_peer_extd_stats { | 4342 | struct wmi_10_4_peer_extd_stats { |
4343 | struct wmi_10_4_peer_stats common; | ||
4344 | struct wmi_mac_addr peer_macaddr; | 4343 | struct wmi_mac_addr peer_macaddr; |
4345 | __le32 inactive_time; | 4344 | __le32 inactive_time; |
4346 | __le32 peer_chain_rssi; | 4345 | __le32 peer_chain_rssi; |
@@ -4348,6 +4347,19 @@ struct wmi_10_4_peer_extd_stats { | |||
4348 | __le32 reserved[10]; | 4347 | __le32 reserved[10]; |
4349 | } __packed; | 4348 | } __packed; |
4350 | 4349 | ||
4350 | struct wmi_10_4_bss_bcn_stats { | ||
4351 | __le32 vdev_id; | ||
4352 | __le32 bss_bcns_dropped; | ||
4353 | __le32 bss_bcn_delivered; | ||
4354 | } __packed; | ||
4355 | |||
4356 | struct wmi_10_4_bss_bcn_filter_stats { | ||
4357 | __le32 bcns_dropped; | ||
4358 | __le32 bcns_delivered; | ||
4359 | __le32 active_filters; | ||
4360 | struct wmi_10_4_bss_bcn_stats bss_stats; | ||
4361 | } __packed; | ||
4362 | |||
4351 | struct wmi_10_2_pdev_ext_stats { | 4363 | struct wmi_10_2_pdev_ext_stats { |
4352 | __le32 rx_rssi_comb; | 4364 | __le32 rx_rssi_comb; |
4353 | __le32 rx_rssi[4]; | 4365 | __le32 rx_rssi[4]; |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index ef5b40ef6d67..4ad6284fc37d 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -847,8 +847,6 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy, | |||
847 | 847 | ||
848 | up(&ar->sem); | 848 | up(&ar->sem); |
849 | 849 | ||
850 | vif->sme_state = SME_DISCONNECTED; | ||
851 | |||
852 | return 0; | 850 | return 0; |
853 | } | 851 | } |
854 | 852 | ||
@@ -1111,7 +1109,8 @@ void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, | |||
1111 | 1109 | ||
1112 | cfg80211_chandef_create(&chandef, | 1110 | cfg80211_chandef_create(&chandef, |
1113 | ieee80211_get_channel(vif->ar->wiphy, freq), | 1111 | ieee80211_get_channel(vif->ar->wiphy, freq), |
1114 | (mode == WMI_11G_HT20) ? | 1112 | (mode == WMI_11G_HT20 && |
1113 | ath6kl_band_2ghz.ht_cap.ht_supported) ? | ||
1115 | NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT); | 1114 | NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT); |
1116 | 1115 | ||
1117 | mutex_lock(&vif->wdev.mtx); | 1116 | mutex_lock(&vif->wdev.mtx); |
@@ -2978,6 +2977,7 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
2978 | 2977 | ||
2979 | ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx); | 2978 | ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx); |
2980 | clear_bit(CONNECTED, &vif->flags); | 2979 | clear_bit(CONNECTED, &vif->flags); |
2980 | netif_carrier_off(vif->ndev); | ||
2981 | 2981 | ||
2982 | /* Restore ht setting in firmware */ | 2982 | /* Restore ht setting in firmware */ |
2983 | return ath6kl_restore_htcap(vif); | 2983 | return ath6kl_restore_htcap(vif); |
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 40432fe7a5d2..9df41d5e3249 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c | |||
@@ -1401,6 +1401,10 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) | |||
1401 | return; | 1401 | return; |
1402 | } | 1402 | } |
1403 | 1403 | ||
1404 | pad_before_data_start = | ||
1405 | (le16_to_cpu(dhdr->info3) >> WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT) | ||
1406 | & WMI_DATA_HDR_PAD_BEFORE_DATA_MASK; | ||
1407 | |||
1404 | /* Get the Power save state of the STA */ | 1408 | /* Get the Power save state of the STA */ |
1405 | if (vif->nw_type == AP_NETWORK) { | 1409 | if (vif->nw_type == AP_NETWORK) { |
1406 | meta_type = wmi_data_hdr_get_meta(dhdr); | 1410 | meta_type = wmi_data_hdr_get_meta(dhdr); |
@@ -1408,7 +1412,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) | |||
1408 | ps_state = !!((dhdr->info >> WMI_DATA_HDR_PS_SHIFT) & | 1412 | ps_state = !!((dhdr->info >> WMI_DATA_HDR_PS_SHIFT) & |
1409 | WMI_DATA_HDR_PS_MASK); | 1413 | WMI_DATA_HDR_PS_MASK); |
1410 | 1414 | ||
1411 | offset = sizeof(struct wmi_data_hdr); | 1415 | offset = sizeof(struct wmi_data_hdr) + pad_before_data_start; |
1412 | trig_state = !!(le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_TRIG); | 1416 | trig_state = !!(le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_TRIG); |
1413 | 1417 | ||
1414 | switch (meta_type) { | 1418 | switch (meta_type) { |
@@ -1523,9 +1527,6 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) | |||
1523 | seq_no = wmi_data_hdr_get_seqno(dhdr); | 1527 | seq_no = wmi_data_hdr_get_seqno(dhdr); |
1524 | meta_type = wmi_data_hdr_get_meta(dhdr); | 1528 | meta_type = wmi_data_hdr_get_meta(dhdr); |
1525 | dot11_hdr = wmi_data_hdr_get_dot11(dhdr); | 1529 | dot11_hdr = wmi_data_hdr_get_dot11(dhdr); |
1526 | pad_before_data_start = | ||
1527 | (le16_to_cpu(dhdr->info3) >> WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT) | ||
1528 | & WMI_DATA_HDR_PAD_BEFORE_DATA_MASK; | ||
1529 | 1530 | ||
1530 | skb_pull(skb, sizeof(struct wmi_data_hdr)); | 1531 | skb_pull(skb, sizeof(struct wmi_data_hdr)); |
1531 | 1532 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index bd4a1a655f42..bea6186f745a 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | #include <linux/nl80211.h> | 19 | #include <linux/nl80211.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/ath9k_platform.h> | ||
22 | #include <linux/module.h> | 21 | #include <linux/module.h> |
23 | #include "ath9k.h" | 22 | #include "ath9k.h" |
24 | 23 | ||
@@ -58,20 +57,9 @@ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) | |||
58 | 57 | ||
59 | static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) | 58 | static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) |
60 | { | 59 | { |
61 | struct ath_softc *sc = (struct ath_softc *)common->priv; | 60 | ath_err(common, "%s: eeprom data has to be provided externally\n", |
62 | struct platform_device *pdev = to_platform_device(sc->dev); | 61 | __func__); |
63 | struct ath9k_platform_data *pdata; | 62 | return false; |
64 | |||
65 | pdata = dev_get_platdata(&pdev->dev); | ||
66 | if (off >= (ARRAY_SIZE(pdata->eeprom_data))) { | ||
67 | ath_err(common, | ||
68 | "%s: flash read failed, offset %08x is out of range\n", | ||
69 | __func__, off); | ||
70 | return false; | ||
71 | } | ||
72 | |||
73 | *data = pdata->eeprom_data[off]; | ||
74 | return true; | ||
75 | } | 63 | } |
76 | 64 | ||
77 | static struct ath_bus_ops ath_ahb_bus_ops = { | 65 | static struct ath_bus_ops ath_ahb_bus_ops = { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index 53d7445a5d12..61a9b85045d2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c | |||
@@ -476,6 +476,7 @@ static void ar9002_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) | |||
476 | static void ar9002_hw_spectral_scan_config(struct ath_hw *ah, | 476 | static void ar9002_hw_spectral_scan_config(struct ath_hw *ah, |
477 | struct ath_spec_scan *param) | 477 | struct ath_spec_scan *param) |
478 | { | 478 | { |
479 | u32 repeat_bit; | ||
479 | u8 count; | 480 | u8 count; |
480 | 481 | ||
481 | if (!param->enabled) { | 482 | if (!param->enabled) { |
@@ -486,12 +487,15 @@ static void ar9002_hw_spectral_scan_config(struct ath_hw *ah, | |||
486 | REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA); | 487 | REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA); |
487 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE); | 488 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE); |
488 | 489 | ||
490 | if (AR_SREV_9280(ah)) | ||
491 | repeat_bit = AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; | ||
492 | else | ||
493 | repeat_bit = AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI; | ||
494 | |||
489 | if (param->short_repeat) | 495 | if (param->short_repeat) |
490 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, | 496 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, repeat_bit); |
491 | AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); | ||
492 | else | 497 | else |
493 | REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, | 498 | REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, repeat_bit); |
494 | AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); | ||
495 | 499 | ||
496 | /* on AR92xx, the highest bit of count will make the the chip send | 500 | /* on AR92xx, the highest bit of count will make the the chip send |
497 | * spectral samples endlessly. Check if this really was intended, | 501 | * spectral samples endlessly. Check if this really was intended, |
@@ -499,15 +503,25 @@ static void ar9002_hw_spectral_scan_config(struct ath_hw *ah, | |||
499 | */ | 503 | */ |
500 | count = param->count; | 504 | count = param->count; |
501 | if (param->endless) { | 505 | if (param->endless) { |
502 | if (AR_SREV_9271(ah)) | 506 | if (AR_SREV_9280(ah)) |
503 | count = 0; | ||
504 | else | ||
505 | count = 0x80; | 507 | count = 0x80; |
508 | else | ||
509 | count = 0; | ||
506 | } else if (count & 0x80) | 510 | } else if (count & 0x80) |
507 | count = 0x7f; | 511 | count = 0x7f; |
512 | else if (!count) | ||
513 | count = 1; | ||
514 | |||
515 | if (AR_SREV_9280(ah)) { | ||
516 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, | ||
517 | AR_PHY_SPECTRAL_SCAN_COUNT, count); | ||
518 | } else { | ||
519 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, | ||
520 | AR_PHY_SPECTRAL_SCAN_COUNT_KIWI, count); | ||
521 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, | ||
522 | AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT); | ||
523 | } | ||
508 | 524 | ||
509 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, | ||
510 | AR_PHY_SPECTRAL_SCAN_COUNT, count); | ||
511 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, | 525 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, |
512 | AR_PHY_SPECTRAL_SCAN_PERIOD, param->period); | 526 | AR_PHY_SPECTRAL_SCAN_PERIOD, param->period); |
513 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, | 527 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 9d17a5375f64..2b58245f774a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h | |||
@@ -177,8 +177,11 @@ | |||
177 | #define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 | 177 | #define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 |
178 | #define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 /* Number of reports, reg 68, bits 16-23*/ | 178 | #define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 /* Number of reports, reg 68, bits 16-23*/ |
179 | #define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 | 179 | #define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 |
180 | #define AR_PHY_SPECTRAL_SCAN_COUNT_KIWI 0x0FFF0000 /* Number of reports, reg 68, bits 16-27*/ | ||
181 | #define AR_PHY_SPECTRAL_SCAN_COUNT_KIWI_S 16 | ||
180 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 /* Short repeat, reg 68, bit 24*/ | 182 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 /* Short repeat, reg 68, bit 24*/ |
181 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 /* Short repeat, reg 68, bit 24*/ | 183 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI 0x10000000 /* Short repeat, reg 68, bit 28*/ |
184 | #define AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT 0x40000000 | ||
182 | 185 | ||
183 | #define AR_PHY_RX_DELAY 0x9914 | 186 | #define AR_PHY_RX_DELAY 0x9914 |
184 | #define AR_PHY_SEARCH_START_DELAY 0x9918 | 187 | #define AR_PHY_SEARCH_START_DELAY 0x9918 |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 518e649ecff3..b6f064a8d264 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -33,6 +33,7 @@ struct coeff { | |||
33 | 33 | ||
34 | enum ar9003_cal_types { | 34 | enum ar9003_cal_types { |
35 | IQ_MISMATCH_CAL = BIT(0), | 35 | IQ_MISMATCH_CAL = BIT(0), |
36 | TEMP_COMP_CAL = BIT(1), | ||
36 | }; | 37 | }; |
37 | 38 | ||
38 | static void ar9003_hw_setup_calibration(struct ath_hw *ah, | 39 | static void ar9003_hw_setup_calibration(struct ath_hw *ah, |
@@ -58,6 +59,12 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, | |||
58 | /* Kick-off cal */ | 59 | /* Kick-off cal */ |
59 | REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL); | 60 | REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL); |
60 | break; | 61 | break; |
62 | case TEMP_COMP_CAL: | ||
63 | ath_dbg(common, CALIBRATE, | ||
64 | "starting Temperature Compensation Calibration\n"); | ||
65 | REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_LOCAL); | ||
66 | REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_START); | ||
67 | break; | ||
61 | default: | 68 | default: |
62 | ath_err(common, "Invalid calibration type\n"); | 69 | ath_err(common, "Invalid calibration type\n"); |
63 | break; | 70 | break; |
@@ -75,50 +82,51 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah, | |||
75 | struct ath9k_cal_list *currCal) | 82 | struct ath9k_cal_list *currCal) |
76 | { | 83 | { |
77 | struct ath9k_hw_cal_data *caldata = ah->caldata; | 84 | struct ath9k_hw_cal_data *caldata = ah->caldata; |
78 | /* Cal is assumed not done until explicitly set below */ | 85 | const struct ath9k_percal_data *cur_caldata = currCal->calData; |
79 | bool iscaldone = false; | ||
80 | 86 | ||
81 | /* Calibration in progress. */ | 87 | /* Calibration in progress. */ |
82 | if (currCal->calState == CAL_RUNNING) { | 88 | if (currCal->calState == CAL_RUNNING) { |
83 | /* Check to see if it has finished. */ | 89 | /* Check to see if it has finished. */ |
84 | if (!(REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) { | 90 | if (REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL) |
91 | return false; | ||
92 | |||
93 | /* | ||
94 | * Accumulate cal measures for active chains | ||
95 | */ | ||
96 | if (cur_caldata->calCollect) | ||
97 | cur_caldata->calCollect(ah); | ||
98 | ah->cal_samples++; | ||
99 | |||
100 | if (ah->cal_samples >= cur_caldata->calNumSamples) { | ||
101 | unsigned int i, numChains = 0; | ||
102 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
103 | if (rxchainmask & (1 << i)) | ||
104 | numChains++; | ||
105 | } | ||
106 | |||
85 | /* | 107 | /* |
86 | * Accumulate cal measures for active chains | 108 | * Process accumulated data |
87 | */ | 109 | */ |
88 | currCal->calData->calCollect(ah); | 110 | if (cur_caldata->calPostProc) |
89 | ah->cal_samples++; | 111 | cur_caldata->calPostProc(ah, numChains); |
90 | |||
91 | if (ah->cal_samples >= | ||
92 | currCal->calData->calNumSamples) { | ||
93 | unsigned int i, numChains = 0; | ||
94 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
95 | if (rxchainmask & (1 << i)) | ||
96 | numChains++; | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * Process accumulated data | ||
101 | */ | ||
102 | currCal->calData->calPostProc(ah, numChains); | ||
103 | 112 | ||
104 | /* Calibration has finished. */ | 113 | /* Calibration has finished. */ |
105 | caldata->CalValid |= currCal->calData->calType; | 114 | caldata->CalValid |= cur_caldata->calType; |
106 | currCal->calState = CAL_DONE; | 115 | currCal->calState = CAL_DONE; |
107 | iscaldone = true; | 116 | return true; |
108 | } else { | 117 | } else { |
109 | /* | 118 | /* |
110 | * Set-up collection of another sub-sample until we | 119 | * Set-up collection of another sub-sample until we |
111 | * get desired number | 120 | * get desired number |
112 | */ | 121 | */ |
113 | ar9003_hw_setup_calibration(ah, currCal); | 122 | ar9003_hw_setup_calibration(ah, currCal); |
114 | } | ||
115 | } | 123 | } |
116 | } else if (!(caldata->CalValid & currCal->calData->calType)) { | 124 | } else if (!(caldata->CalValid & cur_caldata->calType)) { |
117 | /* If current cal is marked invalid in channel, kick it off */ | 125 | /* If current cal is marked invalid in channel, kick it off */ |
118 | ath9k_hw_reset_calibration(ah, currCal); | 126 | ath9k_hw_reset_calibration(ah, currCal); |
119 | } | 127 | } |
120 | 128 | ||
121 | return iscaldone; | 129 | return false; |
122 | } | 130 | } |
123 | 131 | ||
124 | static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, | 132 | static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, |
@@ -315,9 +323,16 @@ static const struct ath9k_percal_data iq_cal_single_sample = { | |||
315 | ar9003_hw_iqcalibrate | 323 | ar9003_hw_iqcalibrate |
316 | }; | 324 | }; |
317 | 325 | ||
326 | static const struct ath9k_percal_data temp_cal_single_sample = { | ||
327 | TEMP_COMP_CAL, | ||
328 | MIN_CAL_SAMPLES, | ||
329 | PER_MAX_LOG_COUNT, | ||
330 | }; | ||
331 | |||
318 | static void ar9003_hw_init_cal_settings(struct ath_hw *ah) | 332 | static void ar9003_hw_init_cal_settings(struct ath_hw *ah) |
319 | { | 333 | { |
320 | ah->iq_caldata.calData = &iq_cal_single_sample; | 334 | ah->iq_caldata.calData = &iq_cal_single_sample; |
335 | ah->temp_caldata.calData = &temp_cal_single_sample; | ||
321 | 336 | ||
322 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 337 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
323 | ah->enabled_cals |= TX_IQ_CAL; | 338 | ah->enabled_cals |= TX_IQ_CAL; |
@@ -325,7 +340,7 @@ static void ar9003_hw_init_cal_settings(struct ath_hw *ah) | |||
325 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; | 340 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; |
326 | } | 341 | } |
327 | 342 | ||
328 | ah->supp_cals = IQ_MISMATCH_CAL; | 343 | ah->supp_cals = IQ_MISMATCH_CAL | TEMP_COMP_CAL; |
329 | } | 344 | } |
330 | 345 | ||
331 | #define OFF_UPPER_LT 24 | 346 | #define OFF_UPPER_LT 24 |
@@ -1374,6 +1389,29 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
1374 | } | 1389 | } |
1375 | } | 1390 | } |
1376 | 1391 | ||
1392 | static void ar9003_hw_init_cal_common(struct ath_hw *ah) | ||
1393 | { | ||
1394 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
1395 | |||
1396 | /* Initialize list pointers */ | ||
1397 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; | ||
1398 | |||
1399 | INIT_CAL(&ah->iq_caldata); | ||
1400 | INSERT_CAL(ah, &ah->iq_caldata); | ||
1401 | |||
1402 | INIT_CAL(&ah->temp_caldata); | ||
1403 | INSERT_CAL(ah, &ah->temp_caldata); | ||
1404 | |||
1405 | /* Initialize current pointer to first element in list */ | ||
1406 | ah->cal_list_curr = ah->cal_list; | ||
1407 | |||
1408 | if (ah->cal_list_curr) | ||
1409 | ath9k_hw_reset_calibration(ah, ah->cal_list_curr); | ||
1410 | |||
1411 | if (caldata) | ||
1412 | caldata->CalValid = 0; | ||
1413 | } | ||
1414 | |||
1377 | static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah, | 1415 | static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah, |
1378 | struct ath9k_channel *chan) | 1416 | struct ath9k_channel *chan) |
1379 | { | 1417 | { |
@@ -1533,21 +1571,7 @@ skip_tx_iqcal: | |||
1533 | /* Revert chainmask to runtime parameters */ | 1571 | /* Revert chainmask to runtime parameters */ |
1534 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | 1572 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); |
1535 | 1573 | ||
1536 | /* Initialize list pointers */ | 1574 | ar9003_hw_init_cal_common(ah); |
1537 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; | ||
1538 | |||
1539 | INIT_CAL(&ah->iq_caldata); | ||
1540 | INSERT_CAL(ah, &ah->iq_caldata); | ||
1541 | ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); | ||
1542 | |||
1543 | /* Initialize current pointer to first element in list */ | ||
1544 | ah->cal_list_curr = ah->cal_list; | ||
1545 | |||
1546 | if (ah->cal_list_curr) | ||
1547 | ath9k_hw_reset_calibration(ah, ah->cal_list_curr); | ||
1548 | |||
1549 | if (caldata) | ||
1550 | caldata->CalValid = 0; | ||
1551 | 1575 | ||
1552 | return true; | 1576 | return true; |
1553 | } | 1577 | } |
@@ -1578,8 +1602,6 @@ static bool do_ar9003_agc_cal(struct ath_hw *ah) | |||
1578 | static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, | 1602 | static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, |
1579 | struct ath9k_channel *chan) | 1603 | struct ath9k_channel *chan) |
1580 | { | 1604 | { |
1581 | struct ath_common *common = ath9k_hw_common(ah); | ||
1582 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
1583 | bool txiqcal_done = false; | 1605 | bool txiqcal_done = false; |
1584 | bool status = true; | 1606 | bool status = true; |
1585 | bool run_agc_cal = false, sep_iq_cal = false; | 1607 | bool run_agc_cal = false, sep_iq_cal = false; |
@@ -1677,21 +1699,7 @@ skip_tx_iqcal: | |||
1677 | /* Revert chainmask to runtime parameters */ | 1699 | /* Revert chainmask to runtime parameters */ |
1678 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | 1700 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); |
1679 | 1701 | ||
1680 | /* Initialize list pointers */ | 1702 | ar9003_hw_init_cal_common(ah); |
1681 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; | ||
1682 | |||
1683 | INIT_CAL(&ah->iq_caldata); | ||
1684 | INSERT_CAL(ah, &ah->iq_caldata); | ||
1685 | ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); | ||
1686 | |||
1687 | /* Initialize current pointer to first element in list */ | ||
1688 | ah->cal_list_curr = ah->cal_list; | ||
1689 | |||
1690 | if (ah->cal_list_curr) | ||
1691 | ath9k_hw_reset_calibration(ah, ah->cal_list_curr); | ||
1692 | |||
1693 | if (caldata) | ||
1694 | caldata->CalValid = 0; | ||
1695 | 1703 | ||
1696 | return true; | 1704 | return true; |
1697 | } | 1705 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index d0224fc58e78..5bd2cbaf582d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -4175,7 +4175,7 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | |||
4175 | if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah)) | 4175 | if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah)) |
4176 | ar9003_hw_internal_regulator_apply(ah); | 4176 | ar9003_hw_internal_regulator_apply(ah); |
4177 | ar9003_hw_apply_tuning_caps(ah); | 4177 | ar9003_hw_apply_tuning_caps(ah); |
4178 | ar9003_hw_apply_minccapwr_thresh(ah, chan); | 4178 | ar9003_hw_apply_minccapwr_thresh(ah, is2ghz); |
4179 | ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz); | 4179 | ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz); |
4180 | ar9003_hw_thermometer_apply(ah); | 4180 | ar9003_hw_thermometer_apply(ah); |
4181 | ar9003_hw_thermo_cal_apply(ah); | 4181 | ar9003_hw_thermo_cal_apply(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 566da789f97e..a171dbb29fbb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -689,13 +689,6 @@ | |||
689 | #define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300) | 689 | #define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300) |
690 | #define AR_CH0_TOP_XPABIASLVL_S (AR_SREV_9550(ah) ? 6 : 8) | 690 | #define AR_CH0_TOP_XPABIASLVL_S (AR_SREV_9550(ah) ? 6 : 8) |
691 | 691 | ||
692 | #define AR_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : \ | ||
693 | ((AR_SREV_9485(ah) ? 0x1628c : 0x16294))) | ||
694 | #define AR_CH0_THERM_XPABIASLVL_MSB 0x3 | ||
695 | #define AR_CH0_THERM_XPABIASLVL_MSB_S 0 | ||
696 | #define AR_CH0_THERM_XPASHORT2GND 0x4 | ||
697 | #define AR_CH0_THERM_XPASHORT2GND_S 2 | ||
698 | |||
699 | #define AR_SWITCH_TABLE_COM_ALL (0xffff) | 692 | #define AR_SWITCH_TABLE_COM_ALL (0xffff) |
700 | #define AR_SWITCH_TABLE_COM_ALL_S (0) | 693 | #define AR_SWITCH_TABLE_COM_ALL_S (0) |
701 | #define AR_SWITCH_TABLE_COM_AR9462_ALL (0xffffff) | 694 | #define AR_SWITCH_TABLE_COM_AR9462_ALL (0xffffff) |
@@ -712,15 +705,17 @@ | |||
712 | #define AR_SWITCH_TABLE_ALL (0xfff) | 705 | #define AR_SWITCH_TABLE_ALL (0xfff) |
713 | #define AR_SWITCH_TABLE_ALL_S (0) | 706 | #define AR_SWITCH_TABLE_ALL_S (0) |
714 | 707 | ||
715 | #define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\ | 708 | #define AR_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\ |
716 | ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16294 : 0x1628c)) | 709 | ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16294 : 0x1628c)) |
710 | #define AR_CH0_THERM_XPABIASLVL_MSB 0x3 | ||
711 | #define AR_CH0_THERM_XPABIASLVL_MSB_S 0 | ||
712 | #define AR_CH0_THERM_XPASHORT2GND 0x4 | ||
713 | #define AR_CH0_THERM_XPASHORT2GND_S 2 | ||
717 | 714 | ||
718 | #define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 | 715 | #define AR_CH0_THERM_LOCAL 0x80000000 |
719 | #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 | 716 | #define AR_CH0_THERM_START 0x20000000 |
720 | #define AR_PHY_65NM_CH0_THERM_START 0x20000000 | 717 | #define AR_CH0_THERM_SAR_ADC_OUT 0x0000ff00 |
721 | #define AR_PHY_65NM_CH0_THERM_START_S 29 | 718 | #define AR_CH0_THERM_SAR_ADC_OUT_S 8 |
722 | #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00 | ||
723 | #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8 | ||
724 | 719 | ||
725 | #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ | 720 | #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ |
726 | (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) | 721 | (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 93b3793cce2f..26fc8ecfe8c4 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -637,6 +637,8 @@ struct ath9k_vif_iter_data { | |||
637 | int nwds; /* number of WDS vifs */ | 637 | int nwds; /* number of WDS vifs */ |
638 | int nadhocs; /* number of adhoc vifs */ | 638 | int nadhocs; /* number of adhoc vifs */ |
639 | int nocbs; /* number of OCB vifs */ | 639 | int nocbs; /* number of OCB vifs */ |
640 | int nbcnvifs; /* number of beaconing vifs */ | ||
641 | struct ieee80211_vif *primary_beacon_vif; | ||
640 | struct ieee80211_vif *primary_sta; | 642 | struct ieee80211_vif *primary_sta; |
641 | }; | 643 | }; |
642 | 644 | ||
@@ -685,10 +687,11 @@ struct ath_beacon { | |||
685 | }; | 687 | }; |
686 | 688 | ||
687 | void ath9k_beacon_tasklet(unsigned long data); | 689 | void ath9k_beacon_tasklet(unsigned long data); |
688 | void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, | 690 | void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *main_vif, |
689 | u32 changed); | 691 | bool beacons); |
690 | void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif); | 692 | void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif); |
691 | void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); | 693 | void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); |
694 | void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc); | ||
692 | void ath9k_set_beacon(struct ath_softc *sc); | 695 | void ath9k_set_beacon(struct ath_softc *sc); |
693 | bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif); | 696 | bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif); |
694 | void ath9k_csa_update(struct ath_softc *sc); | 697 | void ath9k_csa_update(struct ath_softc *sc); |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 5cf0cd7cb2d1..e36f947e19fc 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -50,7 +50,7 @@ static void ath9k_beaconq_config(struct ath_softc *sc) | |||
50 | txq = sc->tx.txq_map[IEEE80211_AC_BE]; | 50 | txq = sc->tx.txq_map[IEEE80211_AC_BE]; |
51 | ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); | 51 | ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); |
52 | qi.tqi_aifs = qi_be.tqi_aifs; | 52 | qi.tqi_aifs = qi_be.tqi_aifs; |
53 | if (ah->slottime == ATH9K_SLOT_TIME_20) | 53 | if (ah->slottime == 20) |
54 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; | 54 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; |
55 | else | 55 | else |
56 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | 56 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; |
@@ -209,7 +209,6 @@ void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
209 | } | 209 | } |
210 | 210 | ||
211 | sc->beacon.bslot[avp->av_bslot] = vif; | 211 | sc->beacon.bslot[avp->av_bslot] = vif; |
212 | sc->nbcnvifs++; | ||
213 | 212 | ||
214 | ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n", | 213 | ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n", |
215 | avp->av_bslot); | 214 | avp->av_bslot); |
@@ -220,15 +219,12 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
220 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 219 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
221 | struct ath_vif *avp = (void *)vif->drv_priv; | 220 | struct ath_vif *avp = (void *)vif->drv_priv; |
222 | struct ath_buf *bf = avp->av_bcbuf; | 221 | struct ath_buf *bf = avp->av_bcbuf; |
223 | struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon; | ||
224 | 222 | ||
225 | ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n", | 223 | ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n", |
226 | avp->av_bslot); | 224 | avp->av_bslot); |
227 | 225 | ||
228 | tasklet_disable(&sc->bcon_tasklet); | 226 | tasklet_disable(&sc->bcon_tasklet); |
229 | 227 | ||
230 | cur_conf->enable_beacon &= ~BIT(avp->av_bslot); | ||
231 | |||
232 | if (bf && bf->bf_mpdu) { | 228 | if (bf && bf->bf_mpdu) { |
233 | struct sk_buff *skb = bf->bf_mpdu; | 229 | struct sk_buff *skb = bf->bf_mpdu; |
234 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | 230 | dma_unmap_single(sc->dev, bf->bf_buf_addr, |
@@ -240,12 +236,73 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
240 | 236 | ||
241 | avp->av_bcbuf = NULL; | 237 | avp->av_bcbuf = NULL; |
242 | sc->beacon.bslot[avp->av_bslot] = NULL; | 238 | sc->beacon.bslot[avp->av_bslot] = NULL; |
243 | sc->nbcnvifs--; | ||
244 | list_add_tail(&bf->list, &sc->beacon.bbuf); | 239 | list_add_tail(&bf->list, &sc->beacon.bbuf); |
245 | 240 | ||
246 | tasklet_enable(&sc->bcon_tasklet); | 241 | tasklet_enable(&sc->bcon_tasklet); |
247 | } | 242 | } |
248 | 243 | ||
244 | void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc) | ||
245 | { | ||
246 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
247 | struct ieee80211_vif *vif; | ||
248 | struct ath_vif *avp; | ||
249 | s64 tsfadjust; | ||
250 | u32 offset; | ||
251 | int first_slot = ATH_BCBUF; | ||
252 | int slot; | ||
253 | |||
254 | tasklet_disable(&sc->bcon_tasklet); | ||
255 | |||
256 | /* Find first taken slot. */ | ||
257 | for (slot = 0; slot < ATH_BCBUF; slot++) { | ||
258 | if (sc->beacon.bslot[slot]) { | ||
259 | first_slot = slot; | ||
260 | break; | ||
261 | } | ||
262 | } | ||
263 | if (first_slot == 0) | ||
264 | goto out; | ||
265 | |||
266 | /* Re-enumarate all slots, moving them forward. */ | ||
267 | for (slot = 0; slot < ATH_BCBUF; slot++) { | ||
268 | if (slot + first_slot < ATH_BCBUF) { | ||
269 | vif = sc->beacon.bslot[slot + first_slot]; | ||
270 | sc->beacon.bslot[slot] = vif; | ||
271 | |||
272 | if (vif) { | ||
273 | avp = (void *)vif->drv_priv; | ||
274 | avp->av_bslot = slot; | ||
275 | } | ||
276 | } else { | ||
277 | sc->beacon.bslot[slot] = NULL; | ||
278 | } | ||
279 | } | ||
280 | |||
281 | vif = sc->beacon.bslot[0]; | ||
282 | if (WARN_ON(!vif)) | ||
283 | goto out; | ||
284 | |||
285 | /* Get the tsf_adjust value for the new first slot. */ | ||
286 | avp = (void *)vif->drv_priv; | ||
287 | tsfadjust = le64_to_cpu(avp->tsf_adjust); | ||
288 | |||
289 | ath_dbg(common, CONFIG, | ||
290 | "Adjusting global TSF after beacon slot reassignment: %lld\n", | ||
291 | (signed long long)tsfadjust); | ||
292 | |||
293 | /* Modify TSF as required and update the HW. */ | ||
294 | avp->chanctx->tsf_val += tsfadjust; | ||
295 | if (sc->cur_chan == avp->chanctx) { | ||
296 | offset = ath9k_hw_get_tsf_offset(&avp->chanctx->tsf_ts, NULL); | ||
297 | ath9k_hw_settsf64(sc->sc_ah, avp->chanctx->tsf_val + offset); | ||
298 | } | ||
299 | |||
300 | /* The slots tsf_adjust will be updated by ath9k_beacon_config later. */ | ||
301 | |||
302 | out: | ||
303 | tasklet_enable(&sc->bcon_tasklet); | ||
304 | } | ||
305 | |||
249 | static int ath9k_beacon_choose_slot(struct ath_softc *sc) | 306 | static int ath9k_beacon_choose_slot(struct ath_softc *sc) |
250 | { | 307 | { |
251 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 308 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -274,22 +331,33 @@ static int ath9k_beacon_choose_slot(struct ath_softc *sc) | |||
274 | return slot; | 331 | return slot; |
275 | } | 332 | } |
276 | 333 | ||
277 | static void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif) | 334 | static void ath9k_set_tsfadjust(struct ath_softc *sc, |
335 | struct ath_beacon_config *cur_conf) | ||
278 | { | 336 | { |
279 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 337 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
280 | struct ath_vif *avp = (void *)vif->drv_priv; | 338 | s64 tsfadjust; |
281 | struct ath_beacon_config *cur_conf = &avp->chanctx->beacon; | 339 | int slot; |
282 | u32 tsfadjust; | ||
283 | 340 | ||
284 | if (avp->av_bslot == 0) | 341 | for (slot = 0; slot < ATH_BCBUF; slot++) { |
285 | return; | 342 | struct ath_vif *avp; |
286 | 343 | ||
287 | tsfadjust = cur_conf->beacon_interval * avp->av_bslot; | 344 | if (!sc->beacon.bslot[slot]) |
288 | tsfadjust = TU_TO_USEC(tsfadjust) / ATH_BCBUF; | 345 | continue; |
289 | avp->tsf_adjust = cpu_to_le64(tsfadjust); | ||
290 | 346 | ||
291 | ath_dbg(common, CONFIG, "tsfadjust is: %llu for bslot: %d\n", | 347 | avp = (void *)sc->beacon.bslot[slot]->drv_priv; |
292 | (unsigned long long)tsfadjust, avp->av_bslot); | 348 | |
349 | /* tsf_adjust is added to the TSF value. We send out the | ||
350 | * beacon late, so need to adjust the TSF starting point to be | ||
351 | * later in time (i.e. the theoretical first beacon has a TSF | ||
352 | * of 0 after correction). | ||
353 | */ | ||
354 | tsfadjust = cur_conf->beacon_interval * avp->av_bslot; | ||
355 | tsfadjust = -TU_TO_USEC(tsfadjust) / ATH_BCBUF; | ||
356 | avp->tsf_adjust = cpu_to_le64(tsfadjust); | ||
357 | |||
358 | ath_dbg(common, CONFIG, "tsfadjust is: %lld for bslot: %d\n", | ||
359 | (signed long long)tsfadjust, avp->av_bslot); | ||
360 | } | ||
293 | } | 361 | } |
294 | 362 | ||
295 | bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif) | 363 | bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif) |
@@ -443,20 +511,28 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
443 | * Both nexttbtt and intval have to be in usecs. | 511 | * Both nexttbtt and intval have to be in usecs. |
444 | */ | 512 | */ |
445 | static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt, | 513 | static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt, |
446 | u32 intval, bool reset_tsf) | 514 | u32 intval) |
447 | { | 515 | { |
448 | struct ath_hw *ah = sc->sc_ah; | 516 | struct ath_hw *ah = sc->sc_ah; |
449 | 517 | ||
450 | ath9k_hw_disable_interrupts(ah); | 518 | ath9k_hw_disable_interrupts(ah); |
451 | if (reset_tsf) | ||
452 | ath9k_hw_reset_tsf(ah); | ||
453 | ath9k_beaconq_config(sc); | 519 | ath9k_beaconq_config(sc); |
454 | ath9k_hw_beaconinit(ah, nexttbtt, intval); | 520 | ath9k_hw_beaconinit(ah, nexttbtt, intval); |
521 | ah->imask |= ATH9K_INT_SWBA; | ||
455 | sc->beacon.bmisscnt = 0; | 522 | sc->beacon.bmisscnt = 0; |
456 | ath9k_hw_set_interrupts(ah); | 523 | ath9k_hw_set_interrupts(ah); |
457 | ath9k_hw_enable_interrupts(ah); | 524 | ath9k_hw_enable_interrupts(ah); |
458 | } | 525 | } |
459 | 526 | ||
527 | static void ath9k_beacon_stop(struct ath_softc *sc) | ||
528 | { | ||
529 | ath9k_hw_disable_interrupts(sc->sc_ah); | ||
530 | sc->sc_ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); | ||
531 | sc->beacon.bmisscnt = 0; | ||
532 | ath9k_hw_set_interrupts(sc->sc_ah); | ||
533 | ath9k_hw_enable_interrupts(sc->sc_ah); | ||
534 | } | ||
535 | |||
460 | /* | 536 | /* |
461 | * For multi-bss ap support beacons are either staggered evenly over N slots or | 537 | * For multi-bss ap support beacons are either staggered evenly over N slots or |
462 | * burst together. For the former arrange for the SWBA to be delivered for each | 538 | * burst together. For the former arrange for the SWBA to be delivered for each |
@@ -468,7 +544,7 @@ static void ath9k_beacon_config_ap(struct ath_softc *sc, | |||
468 | struct ath_hw *ah = sc->sc_ah; | 544 | struct ath_hw *ah = sc->sc_ah; |
469 | 545 | ||
470 | ath9k_cmn_beacon_config_ap(ah, conf, ATH_BCBUF); | 546 | ath9k_cmn_beacon_config_ap(ah, conf, ATH_BCBUF); |
471 | ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, false); | 547 | ath9k_beacon_init(sc, conf->nexttbtt, conf->intval); |
472 | } | 548 | } |
473 | 549 | ||
474 | static void ath9k_beacon_config_sta(struct ath_hw *ah, | 550 | static void ath9k_beacon_config_sta(struct ath_hw *ah, |
@@ -497,7 +573,7 @@ static void ath9k_beacon_config_adhoc(struct ath_softc *sc, | |||
497 | 573 | ||
498 | ath9k_cmn_beacon_config_adhoc(ah, conf); | 574 | ath9k_cmn_beacon_config_adhoc(ah, conf); |
499 | 575 | ||
500 | ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, conf->ibss_creator); | 576 | ath9k_beacon_init(sc, conf->nexttbtt, conf->intval); |
501 | 577 | ||
502 | /* | 578 | /* |
503 | * Set the global 'beacon has been configured' flag for the | 579 | * Set the global 'beacon has been configured' flag for the |
@@ -507,44 +583,6 @@ static void ath9k_beacon_config_adhoc(struct ath_softc *sc, | |||
507 | set_bit(ATH_OP_BEACONS, &common->op_flags); | 583 | set_bit(ATH_OP_BEACONS, &common->op_flags); |
508 | } | 584 | } |
509 | 585 | ||
510 | static bool ath9k_allow_beacon_config(struct ath_softc *sc, | ||
511 | struct ieee80211_vif *vif) | ||
512 | { | ||
513 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
514 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
515 | |||
516 | if (ath9k_is_chanctx_enabled()) { | ||
517 | /* | ||
518 | * If the VIF is not present in the current channel context, | ||
519 | * then we can't do the usual opmode checks. Allow the | ||
520 | * beacon config for the VIF to be updated in this case and | ||
521 | * return immediately. | ||
522 | */ | ||
523 | if (sc->cur_chan != avp->chanctx) | ||
524 | return true; | ||
525 | } | ||
526 | |||
527 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { | ||
528 | if (vif->type != NL80211_IFTYPE_AP) { | ||
529 | ath_dbg(common, CONFIG, | ||
530 | "An AP interface is already present !\n"); | ||
531 | return false; | ||
532 | } | ||
533 | } | ||
534 | |||
535 | if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { | ||
536 | if ((vif->type == NL80211_IFTYPE_STATION) && | ||
537 | test_bit(ATH_OP_BEACONS, &common->op_flags) && | ||
538 | vif != sc->cur_chan->primary_sta) { | ||
539 | ath_dbg(common, CONFIG, | ||
540 | "Beacon already configured for a station interface\n"); | ||
541 | return false; | ||
542 | } | ||
543 | } | ||
544 | |||
545 | return true; | ||
546 | } | ||
547 | |||
548 | static void ath9k_cache_beacon_config(struct ath_softc *sc, | 586 | static void ath9k_cache_beacon_config(struct ath_softc *sc, |
549 | struct ath_chanctx *ctx, | 587 | struct ath_chanctx *ctx, |
550 | struct ieee80211_bss_conf *bss_conf) | 588 | struct ieee80211_bss_conf *bss_conf) |
@@ -580,87 +618,79 @@ static void ath9k_cache_beacon_config(struct ath_softc *sc, | |||
580 | if (cur_conf->dtim_period == 0) | 618 | if (cur_conf->dtim_period == 0) |
581 | cur_conf->dtim_period = 1; | 619 | cur_conf->dtim_period = 1; |
582 | 620 | ||
621 | ath9k_set_tsfadjust(sc, cur_conf); | ||
583 | } | 622 | } |
584 | 623 | ||
585 | void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, | 624 | void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *main_vif, |
586 | u32 changed) | 625 | bool beacons) |
587 | { | 626 | { |
588 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 627 | struct ath_hw *ah = sc->sc_ah; |
589 | struct ath_hw *ah = sc->sc_ah; | 628 | struct ath_common *common = ath9k_hw_common(ah); |
590 | struct ath_common *common = ath9k_hw_common(ah); | 629 | struct ath_vif *avp; |
591 | struct ath_vif *avp = (void *)vif->drv_priv; | 630 | struct ath_chanctx *ctx; |
592 | struct ath_chanctx *ctx = avp->chanctx; | ||
593 | struct ath_beacon_config *cur_conf; | 631 | struct ath_beacon_config *cur_conf; |
594 | unsigned long flags; | 632 | unsigned long flags; |
633 | bool enabled; | ||
595 | bool skip_beacon = false; | 634 | bool skip_beacon = false; |
596 | 635 | ||
597 | if (!ctx) | 636 | if (!beacons) { |
637 | clear_bit(ATH_OP_BEACONS, &common->op_flags); | ||
638 | ath9k_beacon_stop(sc); | ||
598 | return; | 639 | return; |
640 | } | ||
599 | 641 | ||
600 | cur_conf = &avp->chanctx->beacon; | 642 | if (WARN_ON(!main_vif)) |
601 | if (vif->type == NL80211_IFTYPE_AP) | ||
602 | ath9k_set_tsfadjust(sc, vif); | ||
603 | |||
604 | if (!ath9k_allow_beacon_config(sc, vif)) | ||
605 | return; | 643 | return; |
606 | 644 | ||
607 | if (vif->type == NL80211_IFTYPE_STATION) { | 645 | avp = (void *)main_vif->drv_priv; |
608 | ath9k_cache_beacon_config(sc, ctx, bss_conf); | 646 | ctx = avp->chanctx; |
609 | if (ctx != sc->cur_chan) | 647 | cur_conf = &ctx->beacon; |
610 | return; | 648 | enabled = cur_conf->enable_beacon; |
649 | cur_conf->enable_beacon = beacons; | ||
650 | |||
651 | if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { | ||
652 | ath9k_cache_beacon_config(sc, ctx, &main_vif->bss_conf); | ||
611 | 653 | ||
612 | ath9k_set_beacon(sc); | 654 | ath9k_set_beacon(sc); |
613 | set_bit(ATH_OP_BEACONS, &common->op_flags); | 655 | set_bit(ATH_OP_BEACONS, &common->op_flags); |
614 | return; | 656 | return; |
615 | } | 657 | } |
616 | 658 | ||
617 | /* | 659 | /* Update the beacon configuration. */ |
618 | * Take care of multiple interfaces when | 660 | ath9k_cache_beacon_config(sc, ctx, &main_vif->bss_conf); |
619 | * enabling/disabling SWBA. | ||
620 | */ | ||
621 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | ||
622 | bool enabled = cur_conf->enable_beacon; | ||
623 | |||
624 | if (!bss_conf->enable_beacon) { | ||
625 | cur_conf->enable_beacon &= ~BIT(avp->av_bslot); | ||
626 | } else { | ||
627 | cur_conf->enable_beacon |= BIT(avp->av_bslot); | ||
628 | if (!enabled) | ||
629 | ath9k_cache_beacon_config(sc, ctx, bss_conf); | ||
630 | } | ||
631 | } | ||
632 | |||
633 | if (ctx != sc->cur_chan) | ||
634 | return; | ||
635 | 661 | ||
636 | /* | 662 | /* |
637 | * Configure the HW beacon registers only when we have a valid | 663 | * Configure the HW beacon registers only when we have a valid |
638 | * beacon interval. | 664 | * beacon interval. |
639 | */ | 665 | */ |
640 | if (cur_conf->beacon_interval) { | 666 | if (cur_conf->beacon_interval) { |
641 | /* | 667 | /* Special case to sync the TSF when joining an existing IBSS. |
642 | * If we are joining an existing IBSS network, start beaconing | 668 | * This is only done if no AP interface is active. |
643 | * only after a TSF-sync has taken place. Ensure that this | 669 | * Note that mac80211 always resets the TSF when creating a new |
644 | * happens by setting the appropriate flags. | 670 | * IBSS interface. |
645 | */ | 671 | */ |
646 | if ((changed & BSS_CHANGED_IBSS) && !bss_conf->ibss_creator && | 672 | if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC && |
647 | bss_conf->enable_beacon) { | 673 | !enabled && beacons && !main_vif->bss_conf.ibss_creator) { |
648 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | 674 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
649 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | 675 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; |
650 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 676 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
651 | skip_beacon = true; | 677 | skip_beacon = true; |
652 | } else { | ||
653 | ath9k_set_beacon(sc); | ||
654 | } | 678 | } |
655 | 679 | ||
656 | /* | 680 | /* |
657 | * Do not set the ATH_OP_BEACONS flag for IBSS joiner mode | 681 | * Do not set the ATH_OP_BEACONS flag for IBSS joiner mode |
658 | * here, it is done in ath9k_beacon_config_adhoc(). | 682 | * here, it is done in ath9k_beacon_config_adhoc(). |
659 | */ | 683 | */ |
660 | if (cur_conf->enable_beacon && !skip_beacon) | 684 | if (beacons && !skip_beacon) { |
661 | set_bit(ATH_OP_BEACONS, &common->op_flags); | 685 | set_bit(ATH_OP_BEACONS, &common->op_flags); |
662 | else | 686 | ath9k_set_beacon(sc); |
687 | } else { | ||
663 | clear_bit(ATH_OP_BEACONS, &common->op_flags); | 688 | clear_bit(ATH_OP_BEACONS, &common->op_flags); |
689 | ath9k_beacon_stop(sc); | ||
690 | } | ||
691 | } else { | ||
692 | clear_bit(ATH_OP_BEACONS, &common->op_flags); | ||
693 | ath9k_beacon_stop(sc); | ||
664 | } | 694 | } |
665 | } | 695 | } |
666 | 696 | ||
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index d23737342f4f..f0ab6f9955e4 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -50,6 +50,7 @@ | |||
50 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) | 50 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) |
51 | 51 | ||
52 | struct ath_beacon_config { | 52 | struct ath_beacon_config { |
53 | struct ieee80211_vif *main_vif; | ||
53 | int beacon_interval; | 54 | int beacon_interval; |
54 | u16 dtim_period; | 55 | u16 dtim_period; |
55 | u16 bmiss_timeout; | 56 | u16 bmiss_timeout; |
diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c index d2ff0fc0484c..7334c9b09e82 100644 --- a/drivers/net/wireless/ath/ath9k/dynack.c +++ b/drivers/net/wireless/ath/ath9k/dynack.c | |||
@@ -280,7 +280,7 @@ EXPORT_SYMBOL(ath_dynack_sample_ack_ts); | |||
280 | void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an) | 280 | void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an) |
281 | { | 281 | { |
282 | /* ackto = slottime + sifs + air delay */ | 282 | /* ackto = slottime + sifs + air delay */ |
283 | u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64; | 283 | u32 ackto = 9 + 16 + 64; |
284 | struct ath_dynack *da = &ah->dynack; | 284 | struct ath_dynack *da = &ah->dynack; |
285 | 285 | ||
286 | an->ackto = ackto; | 286 | an->ackto = ackto; |
@@ -315,7 +315,7 @@ EXPORT_SYMBOL(ath_dynack_node_deinit); | |||
315 | void ath_dynack_reset(struct ath_hw *ah) | 315 | void ath_dynack_reset(struct ath_hw *ah) |
316 | { | 316 | { |
317 | /* ackto = slottime + sifs + air delay */ | 317 | /* ackto = slottime + sifs + air delay */ |
318 | u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64; | 318 | u32 ackto = 9 + 16 + 64; |
319 | struct ath_dynack *da = &ah->dynack; | 319 | struct ath_dynack *da = &ah->dynack; |
320 | 320 | ||
321 | da->lto = jiffies; | 321 | da->lto = jiffies; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index a794157a147d..a449588a8009 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "hw.h" | 17 | #include "hw.h" |
18 | #include <linux/ath9k_platform.h> | ||
18 | 19 | ||
19 | void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val) | 20 | void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val) |
20 | { | 21 | { |
@@ -108,26 +109,42 @@ void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data, | |||
108 | } | 109 | } |
109 | } | 110 | } |
110 | 111 | ||
111 | static bool ath9k_hw_nvram_read_blob(struct ath_hw *ah, u32 off, | 112 | static bool ath9k_hw_nvram_read_array(u16 *blob, size_t blob_size, |
112 | u16 *data) | 113 | off_t offset, u16 *data) |
113 | { | 114 | { |
114 | u16 *blob_data; | 115 | if (offset > blob_size) |
115 | |||
116 | if (off * sizeof(u16) > ah->eeprom_blob->size) | ||
117 | return false; | 116 | return false; |
118 | 117 | ||
119 | blob_data = (u16 *)ah->eeprom_blob->data; | 118 | *data = blob[offset]; |
120 | *data = blob_data[off]; | ||
121 | return true; | 119 | return true; |
122 | } | 120 | } |
123 | 121 | ||
122 | static bool ath9k_hw_nvram_read_pdata(struct ath9k_platform_data *pdata, | ||
123 | off_t offset, u16 *data) | ||
124 | { | ||
125 | return ath9k_hw_nvram_read_array(pdata->eeprom_data, | ||
126 | ARRAY_SIZE(pdata->eeprom_data), | ||
127 | offset, data); | ||
128 | } | ||
129 | |||
130 | static bool ath9k_hw_nvram_read_firmware(const struct firmware *eeprom_blob, | ||
131 | off_t offset, u16 *data) | ||
132 | { | ||
133 | return ath9k_hw_nvram_read_array((u16 *) eeprom_blob->data, | ||
134 | eeprom_blob->size / sizeof(u16), | ||
135 | offset, data); | ||
136 | } | ||
137 | |||
124 | bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data) | 138 | bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data) |
125 | { | 139 | { |
126 | struct ath_common *common = ath9k_hw_common(ah); | 140 | struct ath_common *common = ath9k_hw_common(ah); |
141 | struct ath9k_platform_data *pdata = ah->dev->platform_data; | ||
127 | bool ret; | 142 | bool ret; |
128 | 143 | ||
129 | if (ah->eeprom_blob) | 144 | if (ah->eeprom_blob) |
130 | ret = ath9k_hw_nvram_read_blob(ah, off, data); | 145 | ret = ath9k_hw_nvram_read_firmware(ah->eeprom_blob, off, data); |
146 | else if (pdata && !pdata->use_eeprom && pdata->eeprom_data) | ||
147 | ret = ath9k_hw_nvram_read_pdata(pdata, off, data); | ||
131 | else | 148 | else |
132 | ret = common->bus_ops->eeprom_read(common, off, data); | 149 | ret = common->bus_ops->eeprom_read(common, off, data); |
133 | 150 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index e6bcb4c90fa0..2c0e4d26e8f9 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -45,7 +45,7 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) | |||
45 | * Long slot time : 2x cwmin | 45 | * Long slot time : 2x cwmin |
46 | * Short slot time : 4x cwmin | 46 | * Short slot time : 4x cwmin |
47 | */ | 47 | */ |
48 | if (ah->slottime == ATH9K_SLOT_TIME_20) | 48 | if (ah->slottime == 20) |
49 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; | 49 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; |
50 | else | 50 | else |
51 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | 51 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index c148c6c504f7..b65c1b661ade 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -678,7 +678,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
678 | 678 | ||
679 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) | 679 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) |
680 | priv->beacon.bslot[i] = NULL; | 680 | priv->beacon.bslot[i] = NULL; |
681 | priv->beacon.slottime = ATH9K_SLOT_TIME_9; | 681 | priv->beacon.slottime = 9; |
682 | 682 | ||
683 | ath9k_cmn_init_channels_rates(common); | 683 | ath9k_cmn_init_channels_rates(common); |
684 | ath9k_cmn_init_crypto(ah); | 684 | ath9k_cmn_init_crypto(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8b2895f9ac7a..d1d0c06d627c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -454,7 +454,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
454 | if (AR_SREV_9100(ah)) | 454 | if (AR_SREV_9100(ah)) |
455 | ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; | 455 | ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; |
456 | 456 | ||
457 | ah->slottime = ATH9K_SLOT_TIME_9; | 457 | ah->slottime = 9; |
458 | ah->globaltxtimeout = (u32) -1; | 458 | ah->globaltxtimeout = (u32) -1; |
459 | ah->power_mode = ATH9K_PM_UNDEFINED; | 459 | ah->power_mode = ATH9K_PM_UNDEFINED; |
460 | ah->htc_reset_init = true; | 460 | ah->htc_reset_init = true; |
@@ -471,33 +471,34 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
471 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); | 471 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); |
472 | } | 472 | } |
473 | 473 | ||
474 | static int ath9k_hw_init_macaddr(struct ath_hw *ah) | 474 | static void ath9k_hw_init_macaddr(struct ath_hw *ah) |
475 | { | 475 | { |
476 | struct ath_common *common = ath9k_hw_common(ah); | 476 | struct ath_common *common = ath9k_hw_common(ah); |
477 | u32 sum; | ||
478 | int i; | 477 | int i; |
479 | u16 eeval; | 478 | u16 eeval; |
480 | static const u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW }; | 479 | static const u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW }; |
481 | 480 | ||
482 | sum = 0; | 481 | /* MAC address may already be loaded via ath9k_platform_data */ |
482 | if (is_valid_ether_addr(common->macaddr)) | ||
483 | return; | ||
484 | |||
483 | for (i = 0; i < 3; i++) { | 485 | for (i = 0; i < 3; i++) { |
484 | eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]); | 486 | eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]); |
485 | sum += eeval; | ||
486 | common->macaddr[2 * i] = eeval >> 8; | 487 | common->macaddr[2 * i] = eeval >> 8; |
487 | common->macaddr[2 * i + 1] = eeval & 0xff; | 488 | common->macaddr[2 * i + 1] = eeval & 0xff; |
488 | } | 489 | } |
489 | if (!is_valid_ether_addr(common->macaddr)) { | ||
490 | ath_err(common, | ||
491 | "eeprom contains invalid mac address: %pM\n", | ||
492 | common->macaddr); | ||
493 | 490 | ||
494 | random_ether_addr(common->macaddr); | 491 | if (is_valid_ether_addr(common->macaddr)) |
495 | ath_err(common, | 492 | return; |
496 | "random mac address will be used: %pM\n", | ||
497 | common->macaddr); | ||
498 | } | ||
499 | 493 | ||
500 | return 0; | 494 | ath_err(common, "eeprom contains invalid mac address: %pM\n", |
495 | common->macaddr); | ||
496 | |||
497 | random_ether_addr(common->macaddr); | ||
498 | ath_err(common, "random mac address will be used: %pM\n", | ||
499 | common->macaddr); | ||
500 | |||
501 | return; | ||
501 | } | 502 | } |
502 | 503 | ||
503 | static int ath9k_hw_post_init(struct ath_hw *ah) | 504 | static int ath9k_hw_post_init(struct ath_hw *ah) |
@@ -636,12 +637,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
636 | if (r) | 637 | if (r) |
637 | return r; | 638 | return r; |
638 | 639 | ||
639 | r = ath9k_hw_init_macaddr(ah); | 640 | ath9k_hw_init_macaddr(ah); |
640 | if (r) { | ||
641 | ath_err(common, "Failed to initialize MAC address\n"); | ||
642 | return r; | ||
643 | } | ||
644 | |||
645 | ath9k_hw_init_hang_checks(ah); | 641 | ath9k_hw_init_hang_checks(ah); |
646 | 642 | ||
647 | common->state = ATH_HW_INITIALIZED; | 643 | common->state = ATH_HW_INITIALIZED; |
@@ -1832,8 +1828,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1832 | u32 saveLedState; | 1828 | u32 saveLedState; |
1833 | u32 saveDefAntenna; | 1829 | u32 saveDefAntenna; |
1834 | u32 macStaId1; | 1830 | u32 macStaId1; |
1831 | struct timespec tsf_ts; | ||
1832 | u32 tsf_offset; | ||
1835 | u64 tsf = 0; | 1833 | u64 tsf = 0; |
1836 | s64 usec = 0; | ||
1837 | int r; | 1834 | int r; |
1838 | bool start_mci_reset = false; | 1835 | bool start_mci_reset = false; |
1839 | bool save_fullsleep = ah->chip_fullsleep; | 1836 | bool save_fullsleep = ah->chip_fullsleep; |
@@ -1877,8 +1874,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1877 | macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; | 1874 | macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; |
1878 | 1875 | ||
1879 | /* Save TSF before chip reset, a cold reset clears it */ | 1876 | /* Save TSF before chip reset, a cold reset clears it */ |
1877 | getrawmonotonic(&tsf_ts); | ||
1880 | tsf = ath9k_hw_gettsf64(ah); | 1878 | tsf = ath9k_hw_gettsf64(ah); |
1881 | usec = ktime_to_us(ktime_get_raw()); | ||
1882 | 1879 | ||
1883 | saveLedState = REG_READ(ah, AR_CFG_LED) & | 1880 | saveLedState = REG_READ(ah, AR_CFG_LED) & |
1884 | (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | | 1881 | (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | |
@@ -1911,8 +1908,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1911 | } | 1908 | } |
1912 | 1909 | ||
1913 | /* Restore TSF */ | 1910 | /* Restore TSF */ |
1914 | usec = ktime_to_us(ktime_get_raw()) - usec; | 1911 | tsf_offset = ath9k_hw_get_tsf_offset(&tsf_ts, NULL); |
1915 | ath9k_hw_settsf64(ah, tsf + usec); | 1912 | ath9k_hw_settsf64(ah, tsf + tsf_offset); |
1916 | 1913 | ||
1917 | if (AR_SREV_9280_20_OR_LATER(ah)) | 1914 | if (AR_SREV_9280_20_OR_LATER(ah)) |
1918 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); | 1915 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); |
@@ -1932,12 +1929,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1932 | /* | 1929 | /* |
1933 | * Some AR91xx SoC devices frequently fail to accept TSF writes | 1930 | * Some AR91xx SoC devices frequently fail to accept TSF writes |
1934 | * right after the chip reset. When that happens, write a new | 1931 | * right after the chip reset. When that happens, write a new |
1935 | * value after the initvals have been applied, with an offset | 1932 | * value after the initvals have been applied. |
1936 | * based on measured time difference | ||
1937 | */ | 1933 | */ |
1938 | if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) { | 1934 | if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) { |
1939 | tsf += 1500; | 1935 | tsf_offset = ath9k_hw_get_tsf_offset(&tsf_ts, NULL); |
1940 | ath9k_hw_settsf64(ah, tsf); | 1936 | ath9k_hw_settsf64(ah, tsf + tsf_offset); |
1941 | } | 1937 | } |
1942 | 1938 | ||
1943 | ath9k_hw_init_mfp(ah); | 1939 | ath9k_hw_init_mfp(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 9cbca1229bac..2a5d3ad1169c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -830,6 +830,7 @@ struct ath_hw { | |||
830 | /* Calibration */ | 830 | /* Calibration */ |
831 | u32 supp_cals; | 831 | u32 supp_cals; |
832 | struct ath9k_cal_list iq_caldata; | 832 | struct ath9k_cal_list iq_caldata; |
833 | struct ath9k_cal_list temp_caldata; | ||
833 | struct ath9k_cal_list adcgain_caldata; | 834 | struct ath9k_cal_list adcgain_caldata; |
834 | struct ath9k_cal_list adcdc_caldata; | 835 | struct ath9k_cal_list adcdc_caldata; |
835 | struct ath9k_cal_list *cal_list; | 836 | struct ath9k_cal_list *cal_list; |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 2ee8624755f7..edc74fca60aa 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -372,7 +372,7 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
372 | 372 | ||
373 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; | 373 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; |
374 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | 374 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); |
375 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; | 375 | sc->beacon.slottime = 9; |
376 | 376 | ||
377 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) | 377 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) |
378 | sc->beacon.bslot[i] = NULL; | 378 | sc->beacon.bslot[i] = NULL; |
@@ -512,31 +512,52 @@ static void ath9k_eeprom_release(struct ath_softc *sc) | |||
512 | release_firmware(sc->sc_ah->eeprom_blob); | 512 | release_firmware(sc->sc_ah->eeprom_blob); |
513 | } | 513 | } |
514 | 514 | ||
515 | static int ath9k_init_soc_platform(struct ath_softc *sc) | 515 | static int ath9k_init_platform(struct ath_softc *sc) |
516 | { | 516 | { |
517 | struct ath9k_platform_data *pdata = sc->dev->platform_data; | 517 | struct ath9k_platform_data *pdata = sc->dev->platform_data; |
518 | struct ath_hw *ah = sc->sc_ah; | 518 | struct ath_hw *ah = sc->sc_ah; |
519 | int ret = 0; | 519 | struct ath_common *common = ath9k_hw_common(ah); |
520 | int ret; | ||
520 | 521 | ||
521 | if (!pdata) | 522 | if (!pdata) |
522 | return 0; | 523 | return 0; |
523 | 524 | ||
525 | if (!pdata->use_eeprom) { | ||
526 | ah->ah_flags &= ~AH_USE_EEPROM; | ||
527 | ah->gpio_mask = pdata->gpio_mask; | ||
528 | ah->gpio_val = pdata->gpio_val; | ||
529 | ah->led_pin = pdata->led_pin; | ||
530 | ah->is_clk_25mhz = pdata->is_clk_25mhz; | ||
531 | ah->get_mac_revision = pdata->get_mac_revision; | ||
532 | ah->external_reset = pdata->external_reset; | ||
533 | ah->disable_2ghz = pdata->disable_2ghz; | ||
534 | ah->disable_5ghz = pdata->disable_5ghz; | ||
535 | |||
536 | if (!pdata->endian_check) | ||
537 | ah->ah_flags |= AH_NO_EEP_SWAP; | ||
538 | } | ||
539 | |||
524 | if (pdata->eeprom_name) { | 540 | if (pdata->eeprom_name) { |
525 | ret = ath9k_eeprom_request(sc, pdata->eeprom_name); | 541 | ret = ath9k_eeprom_request(sc, pdata->eeprom_name); |
526 | if (ret) | 542 | if (ret) |
527 | return ret; | 543 | return ret; |
528 | } | 544 | } |
529 | 545 | ||
546 | if (pdata->led_active_high) | ||
547 | ah->config.led_active_high = true; | ||
548 | |||
530 | if (pdata->tx_gain_buffalo) | 549 | if (pdata->tx_gain_buffalo) |
531 | ah->config.tx_gain_buffalo = true; | 550 | ah->config.tx_gain_buffalo = true; |
532 | 551 | ||
533 | return ret; | 552 | if (pdata->macaddr) |
553 | ether_addr_copy(common->macaddr, pdata->macaddr); | ||
554 | |||
555 | return 0; | ||
534 | } | 556 | } |
535 | 557 | ||
536 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | 558 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, |
537 | const struct ath_bus_ops *bus_ops) | 559 | const struct ath_bus_ops *bus_ops) |
538 | { | 560 | { |
539 | struct ath9k_platform_data *pdata = sc->dev->platform_data; | ||
540 | struct ath_hw *ah = NULL; | 561 | struct ath_hw *ah = NULL; |
541 | struct ath9k_hw_capabilities *pCap; | 562 | struct ath9k_hw_capabilities *pCap; |
542 | struct ath_common *common; | 563 | struct ath_common *common; |
@@ -550,6 +571,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
550 | ah->dev = sc->dev; | 571 | ah->dev = sc->dev; |
551 | ah->hw = sc->hw; | 572 | ah->hw = sc->hw; |
552 | ah->hw_version.devid = devid; | 573 | ah->hw_version.devid = devid; |
574 | ah->ah_flags |= AH_USE_EEPROM; | ||
575 | ah->led_pin = -1; | ||
553 | ah->reg_ops.read = ath9k_ioread32; | 576 | ah->reg_ops.read = ath9k_ioread32; |
554 | ah->reg_ops.multi_read = ath9k_multi_ioread32; | 577 | ah->reg_ops.multi_read = ath9k_multi_ioread32; |
555 | ah->reg_ops.write = ath9k_iowrite32; | 578 | ah->reg_ops.write = ath9k_iowrite32; |
@@ -569,22 +592,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
569 | if (!ath9k_is_chanctx_enabled()) | 592 | if (!ath9k_is_chanctx_enabled()) |
570 | sc->cur_chan->hw_queue_base = 0; | 593 | sc->cur_chan->hw_queue_base = 0; |
571 | 594 | ||
572 | if (!pdata || pdata->use_eeprom) { | ||
573 | ah->ah_flags |= AH_USE_EEPROM; | ||
574 | sc->sc_ah->led_pin = -1; | ||
575 | } else { | ||
576 | sc->sc_ah->gpio_mask = pdata->gpio_mask; | ||
577 | sc->sc_ah->gpio_val = pdata->gpio_val; | ||
578 | sc->sc_ah->led_pin = pdata->led_pin; | ||
579 | ah->is_clk_25mhz = pdata->is_clk_25mhz; | ||
580 | ah->get_mac_revision = pdata->get_mac_revision; | ||
581 | ah->external_reset = pdata->external_reset; | ||
582 | ah->disable_2ghz = pdata->disable_2ghz; | ||
583 | ah->disable_5ghz = pdata->disable_5ghz; | ||
584 | if (!pdata->endian_check) | ||
585 | ah->ah_flags |= AH_NO_EEP_SWAP; | ||
586 | } | ||
587 | |||
588 | common->ops = &ah->reg_ops; | 595 | common->ops = &ah->reg_ops; |
589 | common->bus_ops = bus_ops; | 596 | common->bus_ops = bus_ops; |
590 | common->ps_ops = &ath9k_ps_ops; | 597 | common->ps_ops = &ath9k_ps_ops; |
@@ -600,7 +607,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
600 | */ | 607 | */ |
601 | ath9k_init_pcoem_platform(sc); | 608 | ath9k_init_pcoem_platform(sc); |
602 | 609 | ||
603 | ret = ath9k_init_soc_platform(sc); | 610 | ret = ath9k_init_platform(sc); |
604 | if (ret) | 611 | if (ret) |
605 | return ret; | 612 | return ret; |
606 | 613 | ||
@@ -646,9 +653,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
646 | if (ret) | 653 | if (ret) |
647 | goto err_hw; | 654 | goto err_hw; |
648 | 655 | ||
649 | if (pdata && pdata->macaddr) | ||
650 | memcpy(common->macaddr, pdata->macaddr, ETH_ALEN); | ||
651 | |||
652 | ret = ath9k_init_queues(sc); | 656 | ret = ath9k_init_queues(sc); |
653 | if (ret) | 657 | if (ret) |
654 | goto err_queues; | 658 | goto err_queues; |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 7fbf7f965f61..3bab01435a86 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -65,10 +65,6 @@ | |||
65 | #define INIT_SSH_RETRY 32 | 65 | #define INIT_SSH_RETRY 32 |
66 | #define INIT_SLG_RETRY 32 | 66 | #define INIT_SLG_RETRY 32 |
67 | 67 | ||
68 | #define ATH9K_SLOT_TIME_6 6 | ||
69 | #define ATH9K_SLOT_TIME_9 9 | ||
70 | #define ATH9K_SLOT_TIME_20 20 | ||
71 | |||
72 | #define ATH9K_TXERR_XRETRY 0x01 | 68 | #define ATH9K_TXERR_XRETRY 0x01 |
73 | #define ATH9K_TXERR_FILT 0x02 | 69 | #define ATH9K_TXERR_FILT 0x02 |
74 | #define ATH9K_TXERR_FIFO 0x04 | 70 | #define ATH9K_TXERR_FIFO 0x04 |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 8b6398850657..7594650f214f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -910,6 +910,22 @@ static bool ath9k_uses_beacons(int type) | |||
910 | } | 910 | } |
911 | } | 911 | } |
912 | 912 | ||
913 | static void ath9k_vif_iter_set_beacon(struct ath9k_vif_iter_data *iter_data, | ||
914 | struct ieee80211_vif *vif) | ||
915 | { | ||
916 | /* Use the first (configured) interface, but prefering AP interfaces. */ | ||
917 | if (!iter_data->primary_beacon_vif) { | ||
918 | iter_data->primary_beacon_vif = vif; | ||
919 | } else { | ||
920 | if (iter_data->primary_beacon_vif->type != NL80211_IFTYPE_AP && | ||
921 | vif->type == NL80211_IFTYPE_AP) | ||
922 | iter_data->primary_beacon_vif = vif; | ||
923 | } | ||
924 | |||
925 | iter_data->beacons = true; | ||
926 | iter_data->nbcnvifs += 1; | ||
927 | } | ||
928 | |||
913 | static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, | 929 | static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, |
914 | u8 *mac, struct ieee80211_vif *vif) | 930 | u8 *mac, struct ieee80211_vif *vif) |
915 | { | 931 | { |
@@ -926,11 +942,13 @@ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, | |||
926 | } | 942 | } |
927 | 943 | ||
928 | if (!vif->bss_conf.use_short_slot) | 944 | if (!vif->bss_conf.use_short_slot) |
929 | iter_data->slottime = ATH9K_SLOT_TIME_20; | 945 | iter_data->slottime = 20; |
930 | 946 | ||
931 | switch (vif->type) { | 947 | switch (vif->type) { |
932 | case NL80211_IFTYPE_AP: | 948 | case NL80211_IFTYPE_AP: |
933 | iter_data->naps++; | 949 | iter_data->naps++; |
950 | if (vif->bss_conf.enable_beacon) | ||
951 | ath9k_vif_iter_set_beacon(iter_data, vif); | ||
934 | break; | 952 | break; |
935 | case NL80211_IFTYPE_STATION: | 953 | case NL80211_IFTYPE_STATION: |
936 | iter_data->nstations++; | 954 | iter_data->nstations++; |
@@ -943,12 +961,12 @@ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, | |||
943 | case NL80211_IFTYPE_ADHOC: | 961 | case NL80211_IFTYPE_ADHOC: |
944 | iter_data->nadhocs++; | 962 | iter_data->nadhocs++; |
945 | if (vif->bss_conf.enable_beacon) | 963 | if (vif->bss_conf.enable_beacon) |
946 | iter_data->beacons = true; | 964 | ath9k_vif_iter_set_beacon(iter_data, vif); |
947 | break; | 965 | break; |
948 | case NL80211_IFTYPE_MESH_POINT: | 966 | case NL80211_IFTYPE_MESH_POINT: |
949 | iter_data->nmeshes++; | 967 | iter_data->nmeshes++; |
950 | if (vif->bss_conf.enable_beacon) | 968 | if (vif->bss_conf.enable_beacon) |
951 | iter_data->beacons = true; | 969 | ath9k_vif_iter_set_beacon(iter_data, vif); |
952 | break; | 970 | break; |
953 | case NL80211_IFTYPE_WDS: | 971 | case NL80211_IFTYPE_WDS: |
954 | iter_data->nwds++; | 972 | iter_data->nwds++; |
@@ -999,7 +1017,7 @@ void ath9k_calculate_iter_data(struct ath_softc *sc, | |||
999 | */ | 1017 | */ |
1000 | memset(iter_data, 0, sizeof(*iter_data)); | 1018 | memset(iter_data, 0, sizeof(*iter_data)); |
1001 | eth_broadcast_addr(iter_data->mask); | 1019 | eth_broadcast_addr(iter_data->mask); |
1002 | iter_data->slottime = ATH9K_SLOT_TIME_9; | 1020 | iter_data->slottime = 9; |
1003 | 1021 | ||
1004 | list_for_each_entry(avp, &ctx->vifs, list) | 1022 | list_for_each_entry(avp, &ctx->vifs, list) |
1005 | ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); | 1023 | ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); |
@@ -1061,7 +1079,7 @@ static void ath9k_set_offchannel_state(struct ath_softc *sc) | |||
1061 | ah->opmode = vif->type; | 1079 | ah->opmode = vif->type; |
1062 | ah->imask &= ~ATH9K_INT_SWBA; | 1080 | ah->imask &= ~ATH9K_INT_SWBA; |
1063 | ah->imask &= ~ATH9K_INT_TSFOOR; | 1081 | ah->imask &= ~ATH9K_INT_TSFOOR; |
1064 | ah->slottime = ATH9K_SLOT_TIME_9; | 1082 | ah->slottime = 9; |
1065 | 1083 | ||
1066 | ath_hw_setbssidmask(common); | 1084 | ath_hw_setbssidmask(common); |
1067 | ath9k_hw_setopmode(ah); | 1085 | ath9k_hw_setopmode(ah); |
@@ -1081,7 +1099,6 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, | |||
1081 | struct ath_hw *ah = sc->sc_ah; | 1099 | struct ath_hw *ah = sc->sc_ah; |
1082 | struct ath_common *common = ath9k_hw_common(ah); | 1100 | struct ath_common *common = ath9k_hw_common(ah); |
1083 | struct ath9k_vif_iter_data iter_data; | 1101 | struct ath9k_vif_iter_data iter_data; |
1084 | struct ath_beacon_config *cur_conf; | ||
1085 | 1102 | ||
1086 | ath_chanctx_check_active(sc, ctx); | 1103 | ath_chanctx_check_active(sc, ctx); |
1087 | 1104 | ||
@@ -1103,13 +1120,12 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, | |||
1103 | ath_hw_setbssidmask(common); | 1120 | ath_hw_setbssidmask(common); |
1104 | 1121 | ||
1105 | if (iter_data.naps > 0) { | 1122 | if (iter_data.naps > 0) { |
1106 | cur_conf = &ctx->beacon; | ||
1107 | ath9k_hw_set_tsfadjust(ah, true); | 1123 | ath9k_hw_set_tsfadjust(ah, true); |
1108 | ah->opmode = NL80211_IFTYPE_AP; | 1124 | ah->opmode = NL80211_IFTYPE_AP; |
1109 | if (cur_conf->enable_beacon) | ||
1110 | iter_data.beacons = true; | ||
1111 | } else { | 1125 | } else { |
1112 | ath9k_hw_set_tsfadjust(ah, false); | 1126 | ath9k_hw_set_tsfadjust(ah, false); |
1127 | if (iter_data.beacons) | ||
1128 | ath9k_beacon_ensure_primary_slot(sc); | ||
1113 | 1129 | ||
1114 | if (iter_data.nmeshes) | 1130 | if (iter_data.nmeshes) |
1115 | ah->opmode = NL80211_IFTYPE_MESH_POINT; | 1131 | ah->opmode = NL80211_IFTYPE_MESH_POINT; |
@@ -1134,7 +1150,6 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, | |||
1134 | ctx->switch_after_beacon = true; | 1150 | ctx->switch_after_beacon = true; |
1135 | } | 1151 | } |
1136 | 1152 | ||
1137 | ah->imask &= ~ATH9K_INT_SWBA; | ||
1138 | if (ah->opmode == NL80211_IFTYPE_STATION) { | 1153 | if (ah->opmode == NL80211_IFTYPE_STATION) { |
1139 | bool changed = (iter_data.primary_sta != ctx->primary_sta); | 1154 | bool changed = (iter_data.primary_sta != ctx->primary_sta); |
1140 | 1155 | ||
@@ -1151,16 +1166,12 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, | |||
1151 | if (ath9k_hw_mci_is_enabled(sc->sc_ah)) | 1166 | if (ath9k_hw_mci_is_enabled(sc->sc_ah)) |
1152 | ath9k_mci_update_wlan_channels(sc, true); | 1167 | ath9k_mci_update_wlan_channels(sc, true); |
1153 | } | 1168 | } |
1154 | } else if (iter_data.beacons) { | ||
1155 | ah->imask |= ATH9K_INT_SWBA; | ||
1156 | } | 1169 | } |
1170 | sc->nbcnvifs = iter_data.nbcnvifs; | ||
1171 | ath9k_beacon_config(sc, iter_data.primary_beacon_vif, | ||
1172 | iter_data.beacons); | ||
1157 | ath9k_hw_set_interrupts(ah); | 1173 | ath9k_hw_set_interrupts(ah); |
1158 | 1174 | ||
1159 | if (iter_data.beacons) | ||
1160 | set_bit(ATH_OP_BEACONS, &common->op_flags); | ||
1161 | else | ||
1162 | clear_bit(ATH_OP_BEACONS, &common->op_flags); | ||
1163 | |||
1164 | if (ah->slottime != iter_data.slottime) { | 1175 | if (ah->slottime != iter_data.slottime) { |
1165 | ah->slottime = iter_data.slottime; | 1176 | ah->slottime = iter_data.slottime; |
1166 | ath9k_hw_init_global_settings(ah); | 1177 | ath9k_hw_init_global_settings(ah); |
@@ -1777,9 +1788,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1777 | if ((changed & BSS_CHANGED_BEACON_ENABLED) || | 1788 | if ((changed & BSS_CHANGED_BEACON_ENABLED) || |
1778 | (changed & BSS_CHANGED_BEACON_INT) || | 1789 | (changed & BSS_CHANGED_BEACON_INT) || |
1779 | (changed & BSS_CHANGED_BEACON_INFO)) { | 1790 | (changed & BSS_CHANGED_BEACON_INFO)) { |
1780 | ath9k_beacon_config(sc, vif, changed); | 1791 | ath9k_calculate_summary_state(sc, avp->chanctx); |
1781 | if (changed & BSS_CHANGED_BEACON_ENABLED) | ||
1782 | ath9k_calculate_summary_state(sc, avp->chanctx); | ||
1783 | } | 1792 | } |
1784 | 1793 | ||
1785 | if ((avp->chanctx == sc->cur_chan) && | 1794 | if ((avp->chanctx == sc->cur_chan) && |
@@ -1788,6 +1797,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1788 | slottime = 9; | 1797 | slottime = 9; |
1789 | else | 1798 | else |
1790 | slottime = 20; | 1799 | slottime = 20; |
1800 | |||
1791 | if (vif->type == NL80211_IFTYPE_AP) { | 1801 | if (vif->type == NL80211_IFTYPE_AP) { |
1792 | /* | 1802 | /* |
1793 | * Defer update, so that connected stations can adjust | 1803 | * Defer update, so that connected stations can adjust |
@@ -1823,11 +1833,19 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1823 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 1833 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
1824 | { | 1834 | { |
1825 | struct ath_softc *sc = hw->priv; | 1835 | struct ath_softc *sc = hw->priv; |
1836 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
1826 | u64 tsf; | 1837 | u64 tsf; |
1827 | 1838 | ||
1828 | mutex_lock(&sc->mutex); | 1839 | mutex_lock(&sc->mutex); |
1829 | ath9k_ps_wakeup(sc); | 1840 | ath9k_ps_wakeup(sc); |
1830 | tsf = ath9k_hw_gettsf64(sc->sc_ah); | 1841 | /* Get current TSF either from HW or kernel time. */ |
1842 | if (sc->cur_chan == avp->chanctx) { | ||
1843 | tsf = ath9k_hw_gettsf64(sc->sc_ah); | ||
1844 | } else { | ||
1845 | tsf = sc->cur_chan->tsf_val + | ||
1846 | ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL); | ||
1847 | } | ||
1848 | tsf += le64_to_cpu(avp->tsf_adjust); | ||
1831 | ath9k_ps_restore(sc); | 1849 | ath9k_ps_restore(sc); |
1832 | mutex_unlock(&sc->mutex); | 1850 | mutex_unlock(&sc->mutex); |
1833 | 1851 | ||
@@ -1839,10 +1857,15 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw, | |||
1839 | u64 tsf) | 1857 | u64 tsf) |
1840 | { | 1858 | { |
1841 | struct ath_softc *sc = hw->priv; | 1859 | struct ath_softc *sc = hw->priv; |
1860 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
1842 | 1861 | ||
1843 | mutex_lock(&sc->mutex); | 1862 | mutex_lock(&sc->mutex); |
1844 | ath9k_ps_wakeup(sc); | 1863 | ath9k_ps_wakeup(sc); |
1845 | ath9k_hw_settsf64(sc->sc_ah, tsf); | 1864 | tsf -= le64_to_cpu(avp->tsf_adjust); |
1865 | getrawmonotonic(&avp->chanctx->tsf_ts); | ||
1866 | if (sc->cur_chan == avp->chanctx) | ||
1867 | ath9k_hw_settsf64(sc->sc_ah, tsf); | ||
1868 | avp->chanctx->tsf_val = tsf; | ||
1846 | ath9k_ps_restore(sc); | 1869 | ath9k_ps_restore(sc); |
1847 | mutex_unlock(&sc->mutex); | 1870 | mutex_unlock(&sc->mutex); |
1848 | } | 1871 | } |
@@ -1850,11 +1873,15 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw, | |||
1850 | static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 1873 | static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
1851 | { | 1874 | { |
1852 | struct ath_softc *sc = hw->priv; | 1875 | struct ath_softc *sc = hw->priv; |
1876 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
1853 | 1877 | ||
1854 | mutex_lock(&sc->mutex); | 1878 | mutex_lock(&sc->mutex); |
1855 | 1879 | ||
1856 | ath9k_ps_wakeup(sc); | 1880 | ath9k_ps_wakeup(sc); |
1857 | ath9k_hw_reset_tsf(sc->sc_ah); | 1881 | getrawmonotonic(&avp->chanctx->tsf_ts); |
1882 | if (sc->cur_chan == avp->chanctx) | ||
1883 | ath9k_hw_reset_tsf(sc->sc_ah); | ||
1884 | avp->chanctx->tsf_val = 0; | ||
1858 | ath9k_ps_restore(sc); | 1885 | ath9k_ps_restore(sc); |
1859 | 1886 | ||
1860 | mutex_unlock(&sc->mutex); | 1887 | mutex_unlock(&sc->mutex); |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 7cdaf40c3057..0dd454acf22a 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/nl80211.h> | 19 | #include <linux/nl80211.h> |
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include <linux/pci-aspm.h> | 21 | #include <linux/pci-aspm.h> |
22 | #include <linux/ath9k_platform.h> | ||
23 | #include <linux/module.h> | 22 | #include <linux/module.h> |
24 | #include "ath9k.h" | 23 | #include "ath9k.h" |
25 | 24 | ||
@@ -786,35 +785,21 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz) | |||
786 | 785 | ||
787 | static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) | 786 | static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) |
788 | { | 787 | { |
789 | struct ath_softc *sc = (struct ath_softc *) common->priv; | 788 | struct ath_hw *ah = (struct ath_hw *) common->ah; |
790 | struct ath9k_platform_data *pdata = sc->dev->platform_data; | 789 | |
791 | 790 | common->ops->read(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S)); | |
792 | if (pdata && !pdata->use_eeprom) { | 791 | |
793 | if (off >= (ARRAY_SIZE(pdata->eeprom_data))) { | 792 | if (!ath9k_hw_wait(ah, |
794 | ath_err(common, | 793 | AR_EEPROM_STATUS_DATA, |
795 | "%s: eeprom read failed, offset %08x is out of range\n", | 794 | AR_EEPROM_STATUS_DATA_BUSY | |
796 | __func__, off); | 795 | AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0, |
797 | } | 796 | AH_WAIT_TIMEOUT)) { |
798 | 797 | return false; | |
799 | *data = pdata->eeprom_data[off]; | ||
800 | } else { | ||
801 | struct ath_hw *ah = (struct ath_hw *) common->ah; | ||
802 | |||
803 | common->ops->read(ah, AR5416_EEPROM_OFFSET + | ||
804 | (off << AR5416_EEPROM_S)); | ||
805 | |||
806 | if (!ath9k_hw_wait(ah, | ||
807 | AR_EEPROM_STATUS_DATA, | ||
808 | AR_EEPROM_STATUS_DATA_BUSY | | ||
809 | AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0, | ||
810 | AH_WAIT_TIMEOUT)) { | ||
811 | return false; | ||
812 | } | ||
813 | |||
814 | *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA), | ||
815 | AR_EEPROM_STATUS_DATA_VAL); | ||
816 | } | 798 | } |
817 | 799 | ||
800 | *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA), | ||
801 | AR_EEPROM_STATUS_DATA_VAL); | ||
802 | |||
818 | return true; | 803 | return true; |
819 | } | 804 | } |
820 | 805 | ||
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c index 8643801f31b6..231fd022f0f5 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c | |||
@@ -35,26 +35,27 @@ void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low) | |||
35 | return ch->head_blk_ctl->bd_cpu_addr; | 35 | return ch->head_blk_ctl->bd_cpu_addr; |
36 | } | 36 | } |
37 | 37 | ||
38 | static void wcn36xx_ccu_write_register(struct wcn36xx *wcn, int addr, int data) | ||
39 | { | ||
40 | wcn36xx_dbg(WCN36XX_DBG_DXE, | ||
41 | "wcn36xx_ccu_write_register: addr=%x, data=%x\n", | ||
42 | addr, data); | ||
43 | |||
44 | writel(data, wcn->ccu_base + addr); | ||
45 | } | ||
46 | |||
38 | static void wcn36xx_dxe_write_register(struct wcn36xx *wcn, int addr, int data) | 47 | static void wcn36xx_dxe_write_register(struct wcn36xx *wcn, int addr, int data) |
39 | { | 48 | { |
40 | wcn36xx_dbg(WCN36XX_DBG_DXE, | 49 | wcn36xx_dbg(WCN36XX_DBG_DXE, |
41 | "wcn36xx_dxe_write_register: addr=%x, data=%x\n", | 50 | "wcn36xx_dxe_write_register: addr=%x, data=%x\n", |
42 | addr, data); | 51 | addr, data); |
43 | 52 | ||
44 | writel(data, wcn->mmio + addr); | 53 | writel(data, wcn->dxe_base + addr); |
45 | } | 54 | } |
46 | 55 | ||
47 | #define wcn36xx_dxe_write_register_x(wcn, reg, reg_data) \ | ||
48 | do { \ | ||
49 | if (wcn->chip_version == WCN36XX_CHIP_3680) \ | ||
50 | wcn36xx_dxe_write_register(wcn, reg ## _3680, reg_data); \ | ||
51 | else \ | ||
52 | wcn36xx_dxe_write_register(wcn, reg ## _3660, reg_data); \ | ||
53 | } while (0) \ | ||
54 | |||
55 | static void wcn36xx_dxe_read_register(struct wcn36xx *wcn, int addr, int *data) | 56 | static void wcn36xx_dxe_read_register(struct wcn36xx *wcn, int addr, int *data) |
56 | { | 57 | { |
57 | *data = readl(wcn->mmio + addr); | 58 | *data = readl(wcn->dxe_base + addr); |
58 | 59 | ||
59 | wcn36xx_dbg(WCN36XX_DBG_DXE, | 60 | wcn36xx_dbg(WCN36XX_DBG_DXE, |
60 | "wcn36xx_dxe_read_register: addr=%x, data=%x\n", | 61 | "wcn36xx_dxe_read_register: addr=%x, data=%x\n", |
@@ -701,9 +702,13 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn) | |||
701 | reg_data = WCN36XX_DXE_REG_RESET; | 702 | reg_data = WCN36XX_DXE_REG_RESET; |
702 | wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CSR_RESET, reg_data); | 703 | wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CSR_RESET, reg_data); |
703 | 704 | ||
704 | /* Setting interrupt path */ | 705 | /* Select channels for rx avail and xfer done interrupts... */ |
705 | reg_data = WCN36XX_DXE_CCU_INT; | 706 | reg_data = (WCN36XX_DXE_INT_CH3_MASK | WCN36XX_DXE_INT_CH1_MASK) << 16 | |
706 | wcn36xx_dxe_write_register_x(wcn, WCN36XX_DXE_REG_CCU_INT, reg_data); | 707 | WCN36XX_DXE_INT_CH0_MASK | WCN36XX_DXE_INT_CH4_MASK; |
708 | if (wcn->is_pronto) | ||
709 | wcn36xx_ccu_write_register(wcn, WCN36XX_CCU_DXE_INT_SELECT_PRONTO, reg_data); | ||
710 | else | ||
711 | wcn36xx_ccu_write_register(wcn, WCN36XX_CCU_DXE_INT_SELECT_RIVA, reg_data); | ||
707 | 712 | ||
708 | /***************************************/ | 713 | /***************************************/ |
709 | /* Init descriptors for TX LOW channel */ | 714 | /* Init descriptors for TX LOW channel */ |
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h b/drivers/net/wireless/ath/wcn36xx/dxe.h index 3eca4f9594f2..c012e807753b 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.h +++ b/drivers/net/wireless/ath/wcn36xx/dxe.h | |||
@@ -28,11 +28,10 @@ H2H_TEST_RX_TX = DMA2 | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | /* DXE registers */ | 30 | /* DXE registers */ |
31 | #define WCN36XX_DXE_MEM_REG 0x202000 | 31 | #define WCN36XX_DXE_MEM_REG 0 |
32 | 32 | ||
33 | #define WCN36XX_DXE_CCU_INT 0xA0011 | 33 | #define WCN36XX_CCU_DXE_INT_SELECT_RIVA 0x310 |
34 | #define WCN36XX_DXE_REG_CCU_INT_3660 0x200b10 | 34 | #define WCN36XX_CCU_DXE_INT_SELECT_PRONTO 0x10dc |
35 | #define WCN36XX_DXE_REG_CCU_INT_3680 0x2050dc | ||
36 | 35 | ||
37 | /* TODO This must calculated properly but not hardcoded */ | 36 | /* TODO This must calculated properly but not hardcoded */ |
38 | #define WCN36XX_DXE_CTRL_TX_L 0x328a44 | 37 | #define WCN36XX_DXE_CTRL_TX_L 0x328a44 |
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h index 658bfb8baabe..4f87ef1e1eb8 100644 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ b/drivers/net/wireless/ath/wcn36xx/hal.h | |||
@@ -4123,7 +4123,7 @@ struct wcn36xx_hal_update_scan_params_req { | |||
4123 | 4123 | ||
4124 | /* Update scan params - sent from host to PNO to be used during PNO | 4124 | /* Update scan params - sent from host to PNO to be used during PNO |
4125 | * scanningx */ | 4125 | * scanningx */ |
4126 | struct update_scan_params_req_ex { | 4126 | struct wcn36xx_hal_update_scan_params_req_ex { |
4127 | 4127 | ||
4128 | struct wcn36xx_hal_msg_header header; | 4128 | struct wcn36xx_hal_msg_header header; |
4129 | 4129 | ||
@@ -4151,7 +4151,7 @@ struct update_scan_params_req_ex { | |||
4151 | 4151 | ||
4152 | /* Cb State */ | 4152 | /* Cb State */ |
4153 | enum phy_chan_bond_state state; | 4153 | enum phy_chan_bond_state state; |
4154 | }; | 4154 | } __packed; |
4155 | 4155 | ||
4156 | /* Update scan params - sent from host to PNO to be used during PNO | 4156 | /* Update scan params - sent from host to PNO to be used during PNO |
4157 | * scanningx */ | 4157 | * scanningx */ |
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index a920d7020148..e1d59da2ad20 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/firmware.h> | 20 | #include <linux/firmware.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/of_address.h> | ||
23 | #include <linux/of_device.h> | ||
22 | #include "wcn36xx.h" | 24 | #include "wcn36xx.h" |
23 | 25 | ||
24 | unsigned int wcn36xx_dbg_mask; | 26 | unsigned int wcn36xx_dbg_mask; |
@@ -259,17 +261,6 @@ static void wcn36xx_feat_caps_info(struct wcn36xx *wcn) | |||
259 | } | 261 | } |
260 | } | 262 | } |
261 | 263 | ||
262 | static void wcn36xx_detect_chip_version(struct wcn36xx *wcn) | ||
263 | { | ||
264 | if (get_feat_caps(wcn->fw_feat_caps, DOT11AC)) { | ||
265 | wcn36xx_info("Chip is 3680\n"); | ||
266 | wcn->chip_version = WCN36XX_CHIP_3680; | ||
267 | } else { | ||
268 | wcn36xx_info("Chip is 3660\n"); | ||
269 | wcn->chip_version = WCN36XX_CHIP_3660; | ||
270 | } | ||
271 | } | ||
272 | |||
273 | static int wcn36xx_start(struct ieee80211_hw *hw) | 264 | static int wcn36xx_start(struct ieee80211_hw *hw) |
274 | { | 265 | { |
275 | struct wcn36xx *wcn = hw->priv; | 266 | struct wcn36xx *wcn = hw->priv; |
@@ -324,9 +315,6 @@ static int wcn36xx_start(struct ieee80211_hw *hw) | |||
324 | wcn36xx_feat_caps_info(wcn); | 315 | wcn36xx_feat_caps_info(wcn); |
325 | } | 316 | } |
326 | 317 | ||
327 | wcn36xx_detect_chip_version(wcn); | ||
328 | wcn36xx_smd_update_cfg(wcn, WCN36XX_HAL_CFG_ENABLE_MC_ADDR_LIST, 1); | ||
329 | |||
330 | /* DMA channel initialization */ | 318 | /* DMA channel initialization */ |
331 | ret = wcn36xx_dxe_init(wcn); | 319 | ret = wcn36xx_dxe_init(wcn); |
332 | if (ret) { | 320 | if (ret) { |
@@ -1064,7 +1052,11 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) | |||
1064 | static int wcn36xx_platform_get_resources(struct wcn36xx *wcn, | 1052 | static int wcn36xx_platform_get_resources(struct wcn36xx *wcn, |
1065 | struct platform_device *pdev) | 1053 | struct platform_device *pdev) |
1066 | { | 1054 | { |
1055 | struct device_node *mmio_node; | ||
1067 | struct resource *res; | 1056 | struct resource *res; |
1057 | int index; | ||
1058 | int ret; | ||
1059 | |||
1068 | /* Set TX IRQ */ | 1060 | /* Set TX IRQ */ |
1069 | res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, | 1061 | res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, |
1070 | "wcnss_wlantx_irq"); | 1062 | "wcnss_wlantx_irq"); |
@@ -1083,19 +1075,40 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn, | |||
1083 | } | 1075 | } |
1084 | wcn->rx_irq = res->start; | 1076 | wcn->rx_irq = res->start; |
1085 | 1077 | ||
1086 | /* Map the memory */ | 1078 | mmio_node = of_parse_phandle(pdev->dev.parent->of_node, "qcom,mmio", 0); |
1087 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 1079 | if (!mmio_node) { |
1088 | "wcnss_mmio"); | 1080 | wcn36xx_err("failed to acquire qcom,mmio reference\n"); |
1089 | if (!res) { | 1081 | return -EINVAL; |
1090 | wcn36xx_err("failed to get mmio\n"); | ||
1091 | return -ENOENT; | ||
1092 | } | 1082 | } |
1093 | wcn->mmio = ioremap(res->start, resource_size(res)); | 1083 | |
1094 | if (!wcn->mmio) { | 1084 | wcn->is_pronto = !!of_device_is_compatible(mmio_node, "qcom,pronto"); |
1095 | wcn36xx_err("failed to map io memory\n"); | 1085 | |
1096 | return -ENOMEM; | 1086 | /* Map the CCU memory */ |
1087 | index = of_property_match_string(mmio_node, "reg-names", "ccu"); | ||
1088 | wcn->ccu_base = of_iomap(mmio_node, index); | ||
1089 | if (!wcn->ccu_base) { | ||
1090 | wcn36xx_err("failed to map ccu memory\n"); | ||
1091 | ret = -ENOMEM; | ||
1092 | goto put_mmio_node; | ||
1097 | } | 1093 | } |
1094 | |||
1095 | /* Map the DXE memory */ | ||
1096 | index = of_property_match_string(mmio_node, "reg-names", "dxe"); | ||
1097 | wcn->dxe_base = of_iomap(mmio_node, index); | ||
1098 | if (!wcn->dxe_base) { | ||
1099 | wcn36xx_err("failed to map dxe memory\n"); | ||
1100 | ret = -ENOMEM; | ||
1101 | goto unmap_ccu; | ||
1102 | } | ||
1103 | |||
1104 | of_node_put(mmio_node); | ||
1098 | return 0; | 1105 | return 0; |
1106 | |||
1107 | unmap_ccu: | ||
1108 | iounmap(wcn->ccu_base); | ||
1109 | put_mmio_node: | ||
1110 | of_node_put(mmio_node); | ||
1111 | return ret; | ||
1099 | } | 1112 | } |
1100 | 1113 | ||
1101 | static int wcn36xx_probe(struct platform_device *pdev) | 1114 | static int wcn36xx_probe(struct platform_device *pdev) |
@@ -1138,7 +1151,8 @@ static int wcn36xx_probe(struct platform_device *pdev) | |||
1138 | return 0; | 1151 | return 0; |
1139 | 1152 | ||
1140 | out_unmap: | 1153 | out_unmap: |
1141 | iounmap(wcn->mmio); | 1154 | iounmap(wcn->ccu_base); |
1155 | iounmap(wcn->dxe_base); | ||
1142 | out_wq: | 1156 | out_wq: |
1143 | ieee80211_free_hw(hw); | 1157 | ieee80211_free_hw(hw); |
1144 | out_err: | 1158 | out_err: |
@@ -1154,7 +1168,8 @@ static int wcn36xx_remove(struct platform_device *pdev) | |||
1154 | mutex_destroy(&wcn->hal_mutex); | 1168 | mutex_destroy(&wcn->hal_mutex); |
1155 | 1169 | ||
1156 | ieee80211_unregister_hw(hw); | 1170 | ieee80211_unregister_hw(hw); |
1157 | iounmap(wcn->mmio); | 1171 | iounmap(wcn->dxe_base); |
1172 | iounmap(wcn->ccu_base); | ||
1158 | ieee80211_free_hw(hw); | 1173 | ieee80211_free_hw(hw); |
1159 | 1174 | ||
1160 | return 0; | 1175 | return 0; |
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index e8b630c4f11e..a443992320f2 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c | |||
@@ -674,22 +674,25 @@ static int wcn36xx_smd_update_scan_params_rsp(void *buf, size_t len) | |||
674 | return 0; | 674 | return 0; |
675 | } | 675 | } |
676 | 676 | ||
677 | int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn) | 677 | int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, |
678 | u8 *channels, size_t channel_count) | ||
678 | { | 679 | { |
679 | struct wcn36xx_hal_update_scan_params_req msg_body; | 680 | struct wcn36xx_hal_update_scan_params_req_ex msg_body; |
680 | int ret = 0; | 681 | int ret = 0; |
681 | 682 | ||
682 | mutex_lock(&wcn->hal_mutex); | 683 | mutex_lock(&wcn->hal_mutex); |
683 | INIT_HAL_MSG(msg_body, WCN36XX_HAL_UPDATE_SCAN_PARAM_REQ); | 684 | INIT_HAL_MSG(msg_body, WCN36XX_HAL_UPDATE_SCAN_PARAM_REQ); |
684 | 685 | ||
685 | msg_body.dot11d_enabled = 0; | 686 | msg_body.dot11d_enabled = false; |
686 | msg_body.dot11d_resolved = 0; | 687 | msg_body.dot11d_resolved = true; |
687 | msg_body.channel_count = 26; | 688 | |
689 | msg_body.channel_count = channel_count; | ||
690 | memcpy(msg_body.channels, channels, channel_count); | ||
688 | msg_body.active_min_ch_time = 60; | 691 | msg_body.active_min_ch_time = 60; |
689 | msg_body.active_max_ch_time = 120; | 692 | msg_body.active_max_ch_time = 120; |
690 | msg_body.passive_min_ch_time = 60; | 693 | msg_body.passive_min_ch_time = 60; |
691 | msg_body.passive_max_ch_time = 110; | 694 | msg_body.passive_max_ch_time = 110; |
692 | msg_body.state = 0; | 695 | msg_body.state = PHY_SINGLE_CHANNEL_CENTERED; |
693 | 696 | ||
694 | PREPARE_HAL_BUF(wcn->hal_buf, msg_body); | 697 | PREPARE_HAL_BUF(wcn->hal_buf, msg_body); |
695 | 698 | ||
@@ -2226,17 +2229,12 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len) | |||
2226 | 2229 | ||
2227 | case WCN36XX_HAL_COEX_IND: | 2230 | case WCN36XX_HAL_COEX_IND: |
2228 | case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: | 2231 | case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: |
2232 | case WCN36XX_HAL_DEL_BA_IND: | ||
2229 | case WCN36XX_HAL_OTA_TX_COMPL_IND: | 2233 | case WCN36XX_HAL_OTA_TX_COMPL_IND: |
2230 | case WCN36XX_HAL_MISSED_BEACON_IND: | 2234 | case WCN36XX_HAL_MISSED_BEACON_IND: |
2231 | case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: | 2235 | case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: |
2232 | msg_ind = kmalloc(sizeof(*msg_ind), GFP_KERNEL); | 2236 | msg_ind = kmalloc(sizeof(*msg_ind) + len, GFP_KERNEL); |
2233 | if (!msg_ind) | 2237 | if (!msg_ind) { |
2234 | goto nomem; | ||
2235 | msg_ind->msg_len = len; | ||
2236 | msg_ind->msg = kmemdup(buf, len, GFP_KERNEL); | ||
2237 | if (!msg_ind->msg) { | ||
2238 | kfree(msg_ind); | ||
2239 | nomem: | ||
2240 | /* | 2238 | /* |
2241 | * FIXME: Do something smarter then just | 2239 | * FIXME: Do something smarter then just |
2242 | * printing an error. | 2240 | * printing an error. |
@@ -2245,10 +2243,14 @@ nomem: | |||
2245 | msg_header->msg_type); | 2243 | msg_header->msg_type); |
2246 | break; | 2244 | break; |
2247 | } | 2245 | } |
2248 | mutex_lock(&wcn->hal_ind_mutex); | 2246 | |
2247 | msg_ind->msg_len = len; | ||
2248 | memcpy(msg_ind->msg, buf, len); | ||
2249 | |||
2250 | spin_lock(&wcn->hal_ind_lock); | ||
2249 | list_add_tail(&msg_ind->list, &wcn->hal_ind_queue); | 2251 | list_add_tail(&msg_ind->list, &wcn->hal_ind_queue); |
2250 | queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work); | 2252 | queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work); |
2251 | mutex_unlock(&wcn->hal_ind_mutex); | 2253 | spin_unlock(&wcn->hal_ind_lock); |
2252 | wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n"); | 2254 | wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n"); |
2253 | break; | 2255 | break; |
2254 | default: | 2256 | default: |
@@ -2262,8 +2264,9 @@ static void wcn36xx_ind_smd_work(struct work_struct *work) | |||
2262 | container_of(work, struct wcn36xx, hal_ind_work); | 2264 | container_of(work, struct wcn36xx, hal_ind_work); |
2263 | struct wcn36xx_hal_msg_header *msg_header; | 2265 | struct wcn36xx_hal_msg_header *msg_header; |
2264 | struct wcn36xx_hal_ind_msg *hal_ind_msg; | 2266 | struct wcn36xx_hal_ind_msg *hal_ind_msg; |
2267 | unsigned long flags; | ||
2265 | 2268 | ||
2266 | mutex_lock(&wcn->hal_ind_mutex); | 2269 | spin_lock_irqsave(&wcn->hal_ind_lock, flags); |
2267 | 2270 | ||
2268 | hal_ind_msg = list_first_entry(&wcn->hal_ind_queue, | 2271 | hal_ind_msg = list_first_entry(&wcn->hal_ind_queue, |
2269 | struct wcn36xx_hal_ind_msg, | 2272 | struct wcn36xx_hal_ind_msg, |
@@ -2273,6 +2276,7 @@ static void wcn36xx_ind_smd_work(struct work_struct *work) | |||
2273 | 2276 | ||
2274 | switch (msg_header->msg_type) { | 2277 | switch (msg_header->msg_type) { |
2275 | case WCN36XX_HAL_COEX_IND: | 2278 | case WCN36XX_HAL_COEX_IND: |
2279 | case WCN36XX_HAL_DEL_BA_IND: | ||
2276 | case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: | 2280 | case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: |
2277 | break; | 2281 | break; |
2278 | case WCN36XX_HAL_OTA_TX_COMPL_IND: | 2282 | case WCN36XX_HAL_OTA_TX_COMPL_IND: |
@@ -2295,9 +2299,8 @@ static void wcn36xx_ind_smd_work(struct work_struct *work) | |||
2295 | msg_header->msg_type); | 2299 | msg_header->msg_type); |
2296 | } | 2300 | } |
2297 | list_del(wcn->hal_ind_queue.next); | 2301 | list_del(wcn->hal_ind_queue.next); |
2298 | kfree(hal_ind_msg->msg); | 2302 | spin_unlock_irqrestore(&wcn->hal_ind_lock, flags); |
2299 | kfree(hal_ind_msg); | 2303 | kfree(hal_ind_msg); |
2300 | mutex_unlock(&wcn->hal_ind_mutex); | ||
2301 | } | 2304 | } |
2302 | int wcn36xx_smd_open(struct wcn36xx *wcn) | 2305 | int wcn36xx_smd_open(struct wcn36xx *wcn) |
2303 | { | 2306 | { |
@@ -2310,7 +2313,7 @@ int wcn36xx_smd_open(struct wcn36xx *wcn) | |||
2310 | } | 2313 | } |
2311 | INIT_WORK(&wcn->hal_ind_work, wcn36xx_ind_smd_work); | 2314 | INIT_WORK(&wcn->hal_ind_work, wcn36xx_ind_smd_work); |
2312 | INIT_LIST_HEAD(&wcn->hal_ind_queue); | 2315 | INIT_LIST_HEAD(&wcn->hal_ind_queue); |
2313 | mutex_init(&wcn->hal_ind_mutex); | 2316 | spin_lock_init(&wcn->hal_ind_lock); |
2314 | 2317 | ||
2315 | ret = wcn->ctrl_ops->open(wcn, wcn36xx_smd_rsp_process); | 2318 | ret = wcn->ctrl_ops->open(wcn, wcn36xx_smd_rsp_process); |
2316 | if (ret) { | 2319 | if (ret) { |
@@ -2330,5 +2333,4 @@ void wcn36xx_smd_close(struct wcn36xx *wcn) | |||
2330 | { | 2333 | { |
2331 | wcn->ctrl_ops->close(); | 2334 | wcn->ctrl_ops->close(); |
2332 | destroy_workqueue(wcn->hal_ind_wq); | 2335 | destroy_workqueue(wcn->hal_ind_wq); |
2333 | mutex_destroy(&wcn->hal_ind_mutex); | ||
2334 | } | 2336 | } |
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h index d93e3fd73831..df80cbbd9d1b 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.h +++ b/drivers/net/wireless/ath/wcn36xx/smd.h | |||
@@ -46,8 +46,8 @@ struct wcn36xx_fw_msg_status_rsp { | |||
46 | 46 | ||
47 | struct wcn36xx_hal_ind_msg { | 47 | struct wcn36xx_hal_ind_msg { |
48 | struct list_head list; | 48 | struct list_head list; |
49 | u8 *msg; | ||
50 | size_t msg_len; | 49 | size_t msg_len; |
50 | u8 msg[]; | ||
51 | }; | 51 | }; |
52 | 52 | ||
53 | struct wcn36xx; | 53 | struct wcn36xx; |
@@ -63,7 +63,7 @@ int wcn36xx_smd_start_scan(struct wcn36xx *wcn); | |||
63 | int wcn36xx_smd_end_scan(struct wcn36xx *wcn); | 63 | int wcn36xx_smd_end_scan(struct wcn36xx *wcn); |
64 | int wcn36xx_smd_finish_scan(struct wcn36xx *wcn, | 64 | int wcn36xx_smd_finish_scan(struct wcn36xx *wcn, |
65 | enum wcn36xx_hal_sys_mode mode); | 65 | enum wcn36xx_hal_sys_mode mode); |
66 | int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn); | 66 | int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t channel_count); |
67 | int wcn36xx_smd_add_sta_self(struct wcn36xx *wcn, struct ieee80211_vif *vif); | 67 | int wcn36xx_smd_add_sta_self(struct wcn36xx *wcn, struct ieee80211_vif *vif); |
68 | int wcn36xx_smd_delete_sta_self(struct wcn36xx *wcn, u8 *addr); | 68 | int wcn36xx_smd_delete_sta_self(struct wcn36xx *wcn, u8 *addr); |
69 | int wcn36xx_smd_delete_sta(struct wcn36xx *wcn, u8 sta_index); | 69 | int wcn36xx_smd_delete_sta(struct wcn36xx *wcn, u8 sta_index); |
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h index 7433d67a5929..22242d18e1fe 100644 --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h | |||
@@ -193,7 +193,7 @@ struct wcn36xx { | |||
193 | u8 fw_minor; | 193 | u8 fw_minor; |
194 | u8 fw_major; | 194 | u8 fw_major; |
195 | u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE]; | 195 | u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE]; |
196 | u32 chip_version; | 196 | bool is_pronto; |
197 | 197 | ||
198 | /* extra byte for the NULL termination */ | 198 | /* extra byte for the NULL termination */ |
199 | u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; | 199 | u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; |
@@ -202,7 +202,8 @@ struct wcn36xx { | |||
202 | /* IRQs */ | 202 | /* IRQs */ |
203 | int tx_irq; | 203 | int tx_irq; |
204 | int rx_irq; | 204 | int rx_irq; |
205 | void __iomem *mmio; | 205 | void __iomem *ccu_base; |
206 | void __iomem *dxe_base; | ||
206 | 207 | ||
207 | struct wcn36xx_platform_ctrl_ops *ctrl_ops; | 208 | struct wcn36xx_platform_ctrl_ops *ctrl_ops; |
208 | /* | 209 | /* |
@@ -215,7 +216,7 @@ struct wcn36xx { | |||
215 | struct completion hal_rsp_compl; | 216 | struct completion hal_rsp_compl; |
216 | struct workqueue_struct *hal_ind_wq; | 217 | struct workqueue_struct *hal_ind_wq; |
217 | struct work_struct hal_ind_work; | 218 | struct work_struct hal_ind_work; |
218 | struct mutex hal_ind_mutex; | 219 | spinlock_t hal_ind_lock; |
219 | struct list_head hal_ind_queue; | 220 | struct list_head hal_ind_queue; |
220 | 221 | ||
221 | /* DXE channels */ | 222 | /* DXE channels */ |
@@ -241,9 +242,6 @@ struct wcn36xx { | |||
241 | 242 | ||
242 | }; | 243 | }; |
243 | 244 | ||
244 | #define WCN36XX_CHIP_3660 0 | ||
245 | #define WCN36XX_CHIP_3680 1 | ||
246 | |||
247 | static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, | 245 | static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, |
248 | u8 major, | 246 | u8 major, |
249 | u8 minor, | 247 | u8 minor, |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c index c4b89d27e2e8..f549c25608d6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -726,8 +726,10 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, | |||
726 | return -ENOMEM; | 726 | return -ENOMEM; |
727 | err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, | 727 | err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, |
728 | glom_skb); | 728 | glom_skb); |
729 | if (err) | 729 | if (err) { |
730 | brcmu_pkt_buf_free_skb(glom_skb); | ||
730 | goto done; | 731 | goto done; |
732 | } | ||
731 | 733 | ||
732 | skb_queue_walk(pktq, skb) { | 734 | skb_queue_walk(pktq, skb) { |
733 | memcpy(skb->data, glom_skb->data, skb->len); | 735 | memcpy(skb->data, glom_skb->data, skb->len); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index b8f7dec212e5..2628d5e12c64 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | |||
@@ -4666,6 +4666,15 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, | |||
4666 | brcmf_err("SET SSID error (%d)\n", err); | 4666 | brcmf_err("SET SSID error (%d)\n", err); |
4667 | goto exit; | 4667 | goto exit; |
4668 | } | 4668 | } |
4669 | |||
4670 | if (settings->hidden_ssid) { | ||
4671 | err = brcmf_fil_iovar_int_set(ifp, "closednet", 1); | ||
4672 | if (err) { | ||
4673 | brcmf_err("closednet error (%d)\n", err); | ||
4674 | goto exit; | ||
4675 | } | ||
4676 | } | ||
4677 | |||
4669 | brcmf_dbg(TRACE, "AP mode configuration complete\n"); | 4678 | brcmf_dbg(TRACE, "AP mode configuration complete\n"); |
4670 | } else if (dev_role == NL80211_IFTYPE_P2P_GO) { | 4679 | } else if (dev_role == NL80211_IFTYPE_P2P_GO) { |
4671 | err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); | 4680 | err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); |
@@ -4724,6 +4733,10 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) | |||
4724 | return err; | 4733 | return err; |
4725 | } | 4734 | } |
4726 | 4735 | ||
4736 | /* First BSS doesn't get a full reset */ | ||
4737 | if (ifp->bsscfgidx == 0) | ||
4738 | brcmf_fil_iovar_int_set(ifp, "closednet", 0); | ||
4739 | |||
4727 | memset(&join_params, 0, sizeof(join_params)); | 4740 | memset(&join_params, 0, sizeof(join_params)); |
4728 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, | 4741 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, |
4729 | &join_params, sizeof(join_params)); | 4742 | &join_params, sizeof(join_params)); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c index cd221ab55062..9f9024a7bd64 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | |||
@@ -2469,10 +2469,22 @@ void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb) | |||
2469 | void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked) | 2469 | void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked) |
2470 | { | 2470 | { |
2471 | struct brcmf_fws_info *fws = drvr->fws; | 2471 | struct brcmf_fws_info *fws = drvr->fws; |
2472 | struct brcmf_if *ifp; | ||
2473 | int i; | ||
2472 | 2474 | ||
2473 | fws->bus_flow_blocked = flow_blocked; | 2475 | if (fws->avoid_queueing) { |
2474 | if (!flow_blocked) | 2476 | for (i = 0; i < BRCMF_MAX_IFS; i++) { |
2475 | brcmf_fws_schedule_deq(fws); | 2477 | ifp = drvr->iflist[i]; |
2476 | else | 2478 | if (!ifp || !ifp->ndev) |
2477 | fws->stats.bus_flow_block++; | 2479 | continue; |
2480 | brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW, | ||
2481 | flow_blocked); | ||
2482 | } | ||
2483 | } else { | ||
2484 | fws->bus_flow_blocked = flow_blocked; | ||
2485 | if (!flow_blocked) | ||
2486 | brcmf_fws_schedule_deq(fws); | ||
2487 | else | ||
2488 | fws->stats.bus_flow_block++; | ||
2489 | } | ||
2478 | } | 2490 | } |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 5fb8b91b9326..68ab3ac15650 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | |||
@@ -3305,10 +3305,6 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus, | |||
3305 | goto err; | 3305 | goto err; |
3306 | } | 3306 | } |
3307 | 3307 | ||
3308 | /* Allow full data communication using DPC from now on. */ | ||
3309 | brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA); | ||
3310 | bcmerror = 0; | ||
3311 | |||
3312 | err: | 3308 | err: |
3313 | brcmf_sdio_clkctl(bus, CLK_SDONLY, false); | 3309 | brcmf_sdio_clkctl(bus, CLK_SDONLY, false); |
3314 | sdio_release_host(bus->sdiodev->func[1]); | 3310 | sdio_release_host(bus->sdiodev->func[1]); |
@@ -4046,6 +4042,9 @@ static void brcmf_sdio_firmware_callback(struct device *dev, | |||
4046 | } | 4042 | } |
4047 | 4043 | ||
4048 | if (err == 0) { | 4044 | if (err == 0) { |
4045 | /* Allow full data communication using DPC from now on. */ | ||
4046 | brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA); | ||
4047 | |||
4049 | err = brcmf_sdiod_intr_register(sdiodev); | 4048 | err = brcmf_sdiod_intr_register(sdiodev); |
4050 | if (err != 0) | 4049 | if (err != 0) |
4051 | brcmf_err("intr register failed:%d\n", err); | 4050 | brcmf_err("intr register failed:%d\n", err); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c index 796f5f9d5d5a..b7df576bb84d 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c | |||
@@ -1079,8 +1079,10 @@ bool dma_rxfill(struct dma_pub *pub) | |||
1079 | 1079 | ||
1080 | pa = dma_map_single(di->dmadev, p->data, di->rxbufsize, | 1080 | pa = dma_map_single(di->dmadev, p->data, di->rxbufsize, |
1081 | DMA_FROM_DEVICE); | 1081 | DMA_FROM_DEVICE); |
1082 | if (dma_mapping_error(di->dmadev, pa)) | 1082 | if (dma_mapping_error(di->dmadev, pa)) { |
1083 | brcmu_pkt_buf_free_skb(p); | ||
1083 | return false; | 1084 | return false; |
1085 | } | ||
1084 | 1086 | ||
1085 | /* save the free packet pointer */ | 1087 | /* save the free packet pointer */ |
1086 | di->rxp[rxout] = p; | 1088 | di->rxp[rxout] = p; |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c index dd9162722495..0ab865de1491 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c | |||
@@ -87,7 +87,7 @@ void | |||
87 | brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel, | 87 | brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel, |
88 | u16 chanspec) | 88 | u16 chanspec) |
89 | { | 89 | { |
90 | struct tx_power power; | 90 | struct tx_power power = { }; |
91 | u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id; | 91 | u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id; |
92 | 92 | ||
93 | /* Clear previous settings */ | 93 | /* Clear previous settings */ |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c index f4d92155fa76..64690c14ff4d 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c | |||
@@ -73,8 +73,8 @@ | |||
73 | /* Highest firmware API version supported */ | 73 | /* Highest firmware API version supported */ |
74 | #define IWL7260_UCODE_API_MAX 17 | 74 | #define IWL7260_UCODE_API_MAX 17 |
75 | #define IWL7265_UCODE_API_MAX 17 | 75 | #define IWL7265_UCODE_API_MAX 17 |
76 | #define IWL7265D_UCODE_API_MAX 21 | 76 | #define IWL7265D_UCODE_API_MAX 24 |
77 | #define IWL3168_UCODE_API_MAX 21 | 77 | #define IWL3168_UCODE_API_MAX 24 |
78 | 78 | ||
79 | /* Lowest firmware API version supported */ | 79 | /* Lowest firmware API version supported */ |
80 | #define IWL7260_UCODE_API_MIN 16 | 80 | #define IWL7260_UCODE_API_MIN 16 |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c index 8bf11c918dfd..6c6725e808d4 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c | |||
@@ -70,8 +70,8 @@ | |||
70 | #include "iwl-agn-hw.h" | 70 | #include "iwl-agn-hw.h" |
71 | 71 | ||
72 | /* Highest firmware API version supported */ | 72 | /* Highest firmware API version supported */ |
73 | #define IWL8000_UCODE_API_MAX 21 | 73 | #define IWL8000_UCODE_API_MAX 24 |
74 | #define IWL8265_UCODE_API_MAX 21 | 74 | #define IWL8265_UCODE_API_MAX 24 |
75 | 75 | ||
76 | /* Lowest firmware API version supported */ | 76 | /* Lowest firmware API version supported */ |
77 | #define IWL8000_UCODE_API_MIN 16 | 77 | #define IWL8000_UCODE_API_MIN 16 |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c index 5c1e71fe45f3..fbaf705f3fa7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #include "iwl-agn-hw.h" | 55 | #include "iwl-agn-hw.h" |
56 | 56 | ||
57 | /* Highest firmware API version supported */ | 57 | /* Highest firmware API version supported */ |
58 | #define IWL9000_UCODE_API_MAX 21 | 58 | #define IWL9000_UCODE_API_MAX 24 |
59 | 59 | ||
60 | /* Lowest firmware API version supported */ | 60 | /* Lowest firmware API version supported */ |
61 | #define IWL9000_UCODE_API_MIN 16 | 61 | #define IWL9000_UCODE_API_MIN 16 |
diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/marvell/libertas/cfg.c index ea4802446618..7ff2efadceca 100644 --- a/drivers/net/wireless/marvell/libertas/cfg.c +++ b/drivers/net/wireless/marvell/libertas/cfg.c | |||
@@ -2044,8 +2044,8 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev) | |||
2044 | 2044 | ||
2045 | 2045 | ||
2046 | 2046 | ||
2047 | int lbs_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, | 2047 | static int lbs_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, |
2048 | bool enabled, int timeout) | 2048 | bool enabled, int timeout) |
2049 | { | 2049 | { |
2050 | struct lbs_private *priv = wiphy_priv(wiphy); | 2050 | struct lbs_private *priv = wiphy_priv(wiphy); |
2051 | 2051 | ||
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 867ab815e16a..a8ff969c95c2 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c | |||
@@ -1936,10 +1936,9 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, | |||
1936 | mwifiex_set_uap_rates(bss_cfg, params); | 1936 | mwifiex_set_uap_rates(bss_cfg, params); |
1937 | 1937 | ||
1938 | if (mwifiex_set_secure_params(priv, bss_cfg, params)) { | 1938 | if (mwifiex_set_secure_params(priv, bss_cfg, params)) { |
1939 | kfree(bss_cfg); | ||
1940 | mwifiex_dbg(priv->adapter, ERROR, | 1939 | mwifiex_dbg(priv->adapter, ERROR, |
1941 | "Failed to parse secuirty parameters!\n"); | 1940 | "Failed to parse secuirty parameters!\n"); |
1942 | return -1; | 1941 | goto out; |
1943 | } | 1942 | } |
1944 | 1943 | ||
1945 | mwifiex_set_ht_params(priv, bss_cfg, params); | 1944 | mwifiex_set_ht_params(priv, bss_cfg, params); |
@@ -1968,7 +1967,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, | |||
1968 | if (mwifiex_11h_activate(priv, false)) { | 1967 | if (mwifiex_11h_activate(priv, false)) { |
1969 | mwifiex_dbg(priv->adapter, ERROR, | 1968 | mwifiex_dbg(priv->adapter, ERROR, |
1970 | "Failed to disable 11h extensions!!"); | 1969 | "Failed to disable 11h extensions!!"); |
1971 | return -1; | 1970 | goto out; |
1972 | } | 1971 | } |
1973 | priv->state_11h.is_11h_active = false; | 1972 | priv->state_11h.is_11h_active = false; |
1974 | } | 1973 | } |
@@ -1976,12 +1975,11 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, | |||
1976 | if (mwifiex_config_start_uap(priv, bss_cfg)) { | 1975 | if (mwifiex_config_start_uap(priv, bss_cfg)) { |
1977 | mwifiex_dbg(priv->adapter, ERROR, | 1976 | mwifiex_dbg(priv->adapter, ERROR, |
1978 | "Failed to start AP\n"); | 1977 | "Failed to start AP\n"); |
1979 | kfree(bss_cfg); | 1978 | goto out; |
1980 | return -1; | ||
1981 | } | 1979 | } |
1982 | 1980 | ||
1983 | if (mwifiex_set_mgmt_ies(priv, ¶ms->beacon)) | 1981 | if (mwifiex_set_mgmt_ies(priv, ¶ms->beacon)) |
1984 | return -1; | 1982 | goto out; |
1985 | 1983 | ||
1986 | if (!netif_carrier_ok(priv->netdev)) | 1984 | if (!netif_carrier_ok(priv->netdev)) |
1987 | netif_carrier_on(priv->netdev); | 1985 | netif_carrier_on(priv->netdev); |
@@ -1990,6 +1988,10 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, | |||
1990 | memcpy(&priv->bss_cfg, bss_cfg, sizeof(priv->bss_cfg)); | 1988 | memcpy(&priv->bss_cfg, bss_cfg, sizeof(priv->bss_cfg)); |
1991 | kfree(bss_cfg); | 1989 | kfree(bss_cfg); |
1992 | return 0; | 1990 | return 0; |
1991 | |||
1992 | out: | ||
1993 | kfree(bss_cfg); | ||
1994 | return -1; | ||
1993 | } | 1995 | } |
1994 | 1996 | ||
1995 | /* | 1997 | /* |
diff --git a/drivers/net/wireless/marvell/mwifiex/ioctl.h b/drivers/net/wireless/marvell/mwifiex/ioctl.h index f5b8fd1fad1b..70429815ff53 100644 --- a/drivers/net/wireless/marvell/mwifiex/ioctl.h +++ b/drivers/net/wireless/marvell/mwifiex/ioctl.h | |||
@@ -343,16 +343,16 @@ enum { | |||
343 | }; | 343 | }; |
344 | 344 | ||
345 | struct mwifiex_ds_reg_rw { | 345 | struct mwifiex_ds_reg_rw { |
346 | __le32 type; | 346 | u32 type; |
347 | __le32 offset; | 347 | u32 offset; |
348 | __le32 value; | 348 | u32 value; |
349 | }; | 349 | }; |
350 | 350 | ||
351 | #define MAX_EEPROM_DATA 256 | 351 | #define MAX_EEPROM_DATA 256 |
352 | 352 | ||
353 | struct mwifiex_ds_read_eeprom { | 353 | struct mwifiex_ds_read_eeprom { |
354 | __le16 offset; | 354 | u16 offset; |
355 | __le16 byte_count; | 355 | u16 byte_count; |
356 | u8 value[MAX_EEPROM_DATA]; | 356 | u8 value[MAX_EEPROM_DATA]; |
357 | }; | 357 | }; |
358 | 358 | ||
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 22fe993b7dbb..453ab6ad4784 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c | |||
@@ -202,7 +202,6 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, | |||
202 | if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops, | 202 | if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops, |
203 | MWIFIEX_PCIE)) { | 203 | MWIFIEX_PCIE)) { |
204 | pr_err("%s failed\n", __func__); | 204 | pr_err("%s failed\n", __func__); |
205 | kfree(card); | ||
206 | return -1; | 205 | return -1; |
207 | } | 206 | } |
208 | 207 | ||
@@ -1617,6 +1616,7 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) | |||
1617 | 1616 | ||
1618 | pkt_len = *((__le16 *)skb->data); | 1617 | pkt_len = *((__le16 *)skb->data); |
1619 | rx_len = le16_to_cpu(pkt_len); | 1618 | rx_len = le16_to_cpu(pkt_len); |
1619 | skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len); | ||
1620 | skb_trim(skb, rx_len); | 1620 | skb_trim(skb, rx_len); |
1621 | skb_pull(skb, INTF_HEADER_LEN); | 1621 | skb_pull(skb, INTF_HEADER_LEN); |
1622 | 1622 | ||
@@ -2301,6 +2301,12 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter) | |||
2301 | } | 2301 | } |
2302 | 2302 | ||
2303 | } | 2303 | } |
2304 | if (!card->msi_enable) { | ||
2305 | spin_lock_irqsave(&adapter->int_lock, flags); | ||
2306 | pcie_ireg |= adapter->int_status; | ||
2307 | adapter->int_status = 0; | ||
2308 | spin_unlock_irqrestore(&adapter->int_lock, flags); | ||
2309 | } | ||
2304 | } | 2310 | } |
2305 | mwifiex_dbg(adapter, INTR, | 2311 | mwifiex_dbg(adapter, INTR, |
2306 | "info: cmd_sent=%d data_sent=%d\n", | 2312 | "info: cmd_sent=%d data_sent=%d\n", |
@@ -2843,7 +2849,6 @@ static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter) | |||
2843 | "MRVL_PCIE", &card->share_irq_ctx); | 2849 | "MRVL_PCIE", &card->share_irq_ctx); |
2844 | if (ret) { | 2850 | if (ret) { |
2845 | pr_err("request_irq failed: ret=%d\n", ret); | 2851 | pr_err("request_irq failed: ret=%d\n", ret); |
2846 | adapter->card = NULL; | ||
2847 | return -1; | 2852 | return -1; |
2848 | } | 2853 | } |
2849 | 2854 | ||
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c index 8c658495bf66..7897037b0992 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c | |||
@@ -1148,9 +1148,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
1148 | cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); | 1148 | cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); |
1149 | mac_reg = &cmd->params.mac_reg; | 1149 | mac_reg = &cmd->params.mac_reg; |
1150 | mac_reg->action = cpu_to_le16(cmd_action); | 1150 | mac_reg->action = cpu_to_le16(cmd_action); |
1151 | mac_reg->offset = | 1151 | mac_reg->offset = cpu_to_le16((u16) reg_rw->offset); |
1152 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 1152 | mac_reg->value = cpu_to_le32(reg_rw->value); |
1153 | mac_reg->value = reg_rw->value; | ||
1154 | break; | 1153 | break; |
1155 | } | 1154 | } |
1156 | case HostCmd_CMD_BBP_REG_ACCESS: | 1155 | case HostCmd_CMD_BBP_REG_ACCESS: |
@@ -1160,9 +1159,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
1160 | cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); | 1159 | cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); |
1161 | bbp_reg = &cmd->params.bbp_reg; | 1160 | bbp_reg = &cmd->params.bbp_reg; |
1162 | bbp_reg->action = cpu_to_le16(cmd_action); | 1161 | bbp_reg->action = cpu_to_le16(cmd_action); |
1163 | bbp_reg->offset = | 1162 | bbp_reg->offset = cpu_to_le16((u16) reg_rw->offset); |
1164 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 1163 | bbp_reg->value = (u8) reg_rw->value; |
1165 | bbp_reg->value = (u8) le32_to_cpu(reg_rw->value); | ||
1166 | break; | 1164 | break; |
1167 | } | 1165 | } |
1168 | case HostCmd_CMD_RF_REG_ACCESS: | 1166 | case HostCmd_CMD_RF_REG_ACCESS: |
@@ -1172,8 +1170,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
1172 | cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); | 1170 | cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); |
1173 | rf_reg = &cmd->params.rf_reg; | 1171 | rf_reg = &cmd->params.rf_reg; |
1174 | rf_reg->action = cpu_to_le16(cmd_action); | 1172 | rf_reg->action = cpu_to_le16(cmd_action); |
1175 | rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 1173 | rf_reg->offset = cpu_to_le16((u16) reg_rw->offset); |
1176 | rf_reg->value = (u8) le32_to_cpu(reg_rw->value); | 1174 | rf_reg->value = (u8) reg_rw->value; |
1177 | break; | 1175 | break; |
1178 | } | 1176 | } |
1179 | case HostCmd_CMD_PMIC_REG_ACCESS: | 1177 | case HostCmd_CMD_PMIC_REG_ACCESS: |
@@ -1183,9 +1181,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
1183 | cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN); | 1181 | cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN); |
1184 | pmic_reg = &cmd->params.pmic_reg; | 1182 | pmic_reg = &cmd->params.pmic_reg; |
1185 | pmic_reg->action = cpu_to_le16(cmd_action); | 1183 | pmic_reg->action = cpu_to_le16(cmd_action); |
1186 | pmic_reg->offset = | 1184 | pmic_reg->offset = cpu_to_le16((u16) reg_rw->offset); |
1187 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 1185 | pmic_reg->value = (u8) reg_rw->value; |
1188 | pmic_reg->value = (u8) le32_to_cpu(reg_rw->value); | ||
1189 | break; | 1186 | break; |
1190 | } | 1187 | } |
1191 | case HostCmd_CMD_CAU_REG_ACCESS: | 1188 | case HostCmd_CMD_CAU_REG_ACCESS: |
@@ -1195,9 +1192,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
1195 | cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); | 1192 | cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); |
1196 | cau_reg = &cmd->params.rf_reg; | 1193 | cau_reg = &cmd->params.rf_reg; |
1197 | cau_reg->action = cpu_to_le16(cmd_action); | 1194 | cau_reg->action = cpu_to_le16(cmd_action); |
1198 | cau_reg->offset = | 1195 | cau_reg->offset = cpu_to_le16((u16) reg_rw->offset); |
1199 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 1196 | cau_reg->value = (u8) reg_rw->value; |
1200 | cau_reg->value = (u8) le32_to_cpu(reg_rw->value); | ||
1201 | break; | 1197 | break; |
1202 | } | 1198 | } |
1203 | case HostCmd_CMD_802_11_EEPROM_ACCESS: | 1199 | case HostCmd_CMD_802_11_EEPROM_ACCESS: |
@@ -1208,8 +1204,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
1208 | 1204 | ||
1209 | cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN); | 1205 | cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN); |
1210 | cmd_eeprom->action = cpu_to_le16(cmd_action); | 1206 | cmd_eeprom->action = cpu_to_le16(cmd_action); |
1211 | cmd_eeprom->offset = rd_eeprom->offset; | 1207 | cmd_eeprom->offset = cpu_to_le16(rd_eeprom->offset); |
1212 | cmd_eeprom->byte_count = rd_eeprom->byte_count; | 1208 | cmd_eeprom->byte_count = cpu_to_le16(rd_eeprom->byte_count); |
1213 | cmd_eeprom->value = 0; | 1209 | cmd_eeprom->value = 0; |
1214 | break; | 1210 | break; |
1215 | } | 1211 | } |
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c index 9050d06998e6..ccf54932e321 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | |||
@@ -786,45 +786,44 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, | |||
786 | switch (type) { | 786 | switch (type) { |
787 | case HostCmd_CMD_MAC_REG_ACCESS: | 787 | case HostCmd_CMD_MAC_REG_ACCESS: |
788 | r.mac = &resp->params.mac_reg; | 788 | r.mac = &resp->params.mac_reg; |
789 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset)); | 789 | reg_rw->offset = (u32) le16_to_cpu(r.mac->offset); |
790 | reg_rw->value = r.mac->value; | 790 | reg_rw->value = le32_to_cpu(r.mac->value); |
791 | break; | 791 | break; |
792 | case HostCmd_CMD_BBP_REG_ACCESS: | 792 | case HostCmd_CMD_BBP_REG_ACCESS: |
793 | r.bbp = &resp->params.bbp_reg; | 793 | r.bbp = &resp->params.bbp_reg; |
794 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset)); | 794 | reg_rw->offset = (u32) le16_to_cpu(r.bbp->offset); |
795 | reg_rw->value = cpu_to_le32((u32) r.bbp->value); | 795 | reg_rw->value = (u32) r.bbp->value; |
796 | break; | 796 | break; |
797 | 797 | ||
798 | case HostCmd_CMD_RF_REG_ACCESS: | 798 | case HostCmd_CMD_RF_REG_ACCESS: |
799 | r.rf = &resp->params.rf_reg; | 799 | r.rf = &resp->params.rf_reg; |
800 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); | 800 | reg_rw->offset = (u32) le16_to_cpu(r.rf->offset); |
801 | reg_rw->value = cpu_to_le32((u32) r.bbp->value); | 801 | reg_rw->value = (u32) r.bbp->value; |
802 | break; | 802 | break; |
803 | case HostCmd_CMD_PMIC_REG_ACCESS: | 803 | case HostCmd_CMD_PMIC_REG_ACCESS: |
804 | r.pmic = &resp->params.pmic_reg; | 804 | r.pmic = &resp->params.pmic_reg; |
805 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset)); | 805 | reg_rw->offset = (u32) le16_to_cpu(r.pmic->offset); |
806 | reg_rw->value = cpu_to_le32((u32) r.pmic->value); | 806 | reg_rw->value = (u32) r.pmic->value; |
807 | break; | 807 | break; |
808 | case HostCmd_CMD_CAU_REG_ACCESS: | 808 | case HostCmd_CMD_CAU_REG_ACCESS: |
809 | r.rf = &resp->params.rf_reg; | 809 | r.rf = &resp->params.rf_reg; |
810 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); | 810 | reg_rw->offset = (u32) le16_to_cpu(r.rf->offset); |
811 | reg_rw->value = cpu_to_le32((u32) r.rf->value); | 811 | reg_rw->value = (u32) r.rf->value; |
812 | break; | 812 | break; |
813 | case HostCmd_CMD_802_11_EEPROM_ACCESS: | 813 | case HostCmd_CMD_802_11_EEPROM_ACCESS: |
814 | r.eeprom = &resp->params.eeprom; | 814 | r.eeprom = &resp->params.eeprom; |
815 | pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count); | 815 | pr_debug("info: EEPROM read len=%x\n", |
816 | if (le16_to_cpu(eeprom->byte_count) < | 816 | le16_to_cpu(r.eeprom->byte_count)); |
817 | le16_to_cpu(r.eeprom->byte_count)) { | 817 | if (eeprom->byte_count < le16_to_cpu(r.eeprom->byte_count)) { |
818 | eeprom->byte_count = cpu_to_le16(0); | 818 | eeprom->byte_count = 0; |
819 | pr_debug("info: EEPROM read length is too big\n"); | 819 | pr_debug("info: EEPROM read length is too big\n"); |
820 | return -1; | 820 | return -1; |
821 | } | 821 | } |
822 | eeprom->offset = r.eeprom->offset; | 822 | eeprom->offset = le16_to_cpu(r.eeprom->offset); |
823 | eeprom->byte_count = r.eeprom->byte_count; | 823 | eeprom->byte_count = le16_to_cpu(r.eeprom->byte_count); |
824 | if (le16_to_cpu(eeprom->byte_count) > 0) | 824 | if (eeprom->byte_count > 0) |
825 | memcpy(&eeprom->value, &r.eeprom->value, | 825 | memcpy(&eeprom->value, &r.eeprom->value, |
826 | le16_to_cpu(r.eeprom->byte_count)); | 826 | min((u16)MAX_EEPROM_DATA, eeprom->byte_count)); |
827 | |||
828 | break; | 827 | break; |
829 | default: | 828 | default: |
830 | return -1; | 829 | return -1; |
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c index 2ba5397272e2..e06647a327b6 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c | |||
@@ -1251,7 +1251,7 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, | |||
1251 | { | 1251 | { |
1252 | u16 cmd_no; | 1252 | u16 cmd_no; |
1253 | 1253 | ||
1254 | switch (le32_to_cpu(reg_rw->type)) { | 1254 | switch (reg_rw->type) { |
1255 | case MWIFIEX_REG_MAC: | 1255 | case MWIFIEX_REG_MAC: |
1256 | cmd_no = HostCmd_CMD_MAC_REG_ACCESS; | 1256 | cmd_no = HostCmd_CMD_MAC_REG_ACCESS; |
1257 | break; | 1257 | break; |
@@ -1286,9 +1286,9 @@ mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type, | |||
1286 | { | 1286 | { |
1287 | struct mwifiex_ds_reg_rw reg_rw; | 1287 | struct mwifiex_ds_reg_rw reg_rw; |
1288 | 1288 | ||
1289 | reg_rw.type = cpu_to_le32(reg_type); | 1289 | reg_rw.type = reg_type; |
1290 | reg_rw.offset = cpu_to_le32(reg_offset); | 1290 | reg_rw.offset = reg_offset; |
1291 | reg_rw.value = cpu_to_le32(reg_value); | 1291 | reg_rw.value = reg_value; |
1292 | 1292 | ||
1293 | return mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_SET); | 1293 | return mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_SET); |
1294 | } | 1294 | } |
@@ -1306,14 +1306,14 @@ mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type, | |||
1306 | int ret; | 1306 | int ret; |
1307 | struct mwifiex_ds_reg_rw reg_rw; | 1307 | struct mwifiex_ds_reg_rw reg_rw; |
1308 | 1308 | ||
1309 | reg_rw.type = cpu_to_le32(reg_type); | 1309 | reg_rw.type = reg_type; |
1310 | reg_rw.offset = cpu_to_le32(reg_offset); | 1310 | reg_rw.offset = reg_offset; |
1311 | ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_GET); | 1311 | ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_GET); |
1312 | 1312 | ||
1313 | if (ret) | 1313 | if (ret) |
1314 | goto done; | 1314 | goto done; |
1315 | 1315 | ||
1316 | *value = le32_to_cpu(reg_rw.value); | 1316 | *value = reg_rw.value; |
1317 | 1317 | ||
1318 | done: | 1318 | done: |
1319 | return ret; | 1319 | return ret; |
@@ -1332,15 +1332,16 @@ mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes, | |||
1332 | int ret; | 1332 | int ret; |
1333 | struct mwifiex_ds_read_eeprom rd_eeprom; | 1333 | struct mwifiex_ds_read_eeprom rd_eeprom; |
1334 | 1334 | ||
1335 | rd_eeprom.offset = cpu_to_le16((u16) offset); | 1335 | rd_eeprom.offset = offset; |
1336 | rd_eeprom.byte_count = cpu_to_le16((u16) bytes); | 1336 | rd_eeprom.byte_count = bytes; |
1337 | 1337 | ||
1338 | /* Send request to firmware */ | 1338 | /* Send request to firmware */ |
1339 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, | 1339 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, |
1340 | HostCmd_ACT_GEN_GET, 0, &rd_eeprom, true); | 1340 | HostCmd_ACT_GEN_GET, 0, &rd_eeprom, true); |
1341 | 1341 | ||
1342 | if (!ret) | 1342 | if (!ret) |
1343 | memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); | 1343 | memcpy(value, rd_eeprom.value, min((u16)MAX_EEPROM_DATA, |
1344 | rd_eeprom.byte_count)); | ||
1344 | return ret; | 1345 | return ret; |
1345 | } | 1346 | } |
1346 | 1347 | ||
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/Makefile index a85419a37651..676e7de27f27 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/Makefile +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/Makefile | |||
@@ -12,4 +12,4 @@ rtl8188ee-objs := \ | |||
12 | 12 | ||
13 | obj-$(CONFIG_RTL8188EE) += rtl8188ee.o | 13 | obj-$(CONFIG_RTL8188EE) += rtl8188ee.o |
14 | 14 | ||
15 | ccflags-y += -Idrivers/net/wireless/rtlwifi -D__CHECK_ENDIAN__ | 15 | ccflags-y += -D__CHECK_ENDIAN__ |
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index ae47c79cb9b6..00a04dfc03d1 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c | |||
@@ -1214,6 +1214,10 @@ static void wl18xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status, | |||
1214 | int_fw_status->counters.tx_voice_released_blks; | 1214 | int_fw_status->counters.tx_voice_released_blks; |
1215 | fw_status->counters.tx_last_rate = | 1215 | fw_status->counters.tx_last_rate = |
1216 | int_fw_status->counters.tx_last_rate; | 1216 | int_fw_status->counters.tx_last_rate; |
1217 | fw_status->counters.tx_last_rate_mbps = | ||
1218 | int_fw_status->counters.tx_last_rate_mbps; | ||
1219 | fw_status->counters.hlid = | ||
1220 | int_fw_status->counters.hlid; | ||
1217 | 1221 | ||
1218 | fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr); | 1222 | fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr); |
1219 | 1223 | ||
@@ -1821,9 +1825,12 @@ static const struct ieee80211_iface_limit wl18xx_iface_limits[] = { | |||
1821 | }, | 1825 | }, |
1822 | { | 1826 | { |
1823 | .max = 1, | 1827 | .max = 1, |
1824 | .types = BIT(NL80211_IFTYPE_AP) | | 1828 | .types = BIT(NL80211_IFTYPE_AP) |
1825 | BIT(NL80211_IFTYPE_P2P_GO) | | 1829 | | BIT(NL80211_IFTYPE_P2P_GO) |
1826 | BIT(NL80211_IFTYPE_P2P_CLIENT), | 1830 | | BIT(NL80211_IFTYPE_P2P_CLIENT) |
1831 | #ifdef CONFIG_MAC80211_MESH | ||
1832 | | BIT(NL80211_IFTYPE_MESH_POINT) | ||
1833 | #endif | ||
1827 | }, | 1834 | }, |
1828 | { | 1835 | { |
1829 | .max = 1, | 1836 | .max = 1, |
@@ -1836,6 +1843,12 @@ static const struct ieee80211_iface_limit wl18xx_iface_ap_limits[] = { | |||
1836 | .max = 2, | 1843 | .max = 2, |
1837 | .types = BIT(NL80211_IFTYPE_AP), | 1844 | .types = BIT(NL80211_IFTYPE_AP), |
1838 | }, | 1845 | }, |
1846 | #ifdef CONFIG_MAC80211_MESH | ||
1847 | { | ||
1848 | .max = 1, | ||
1849 | .types = BIT(NL80211_IFTYPE_MESH_POINT), | ||
1850 | }, | ||
1851 | #endif | ||
1839 | { | 1852 | { |
1840 | .max = 1, | 1853 | .max = 1, |
1841 | .types = BIT(NL80211_IFTYPE_P2P_DEVICE), | 1854 | .types = BIT(NL80211_IFTYPE_P2P_DEVICE), |
diff --git a/drivers/net/wireless/ti/wl18xx/tx.c b/drivers/net/wireless/ti/wl18xx/tx.c index ebaf66ef3f84..876aef10f95a 100644 --- a/drivers/net/wireless/ti/wl18xx/tx.c +++ b/drivers/net/wireless/ti/wl18xx/tx.c | |||
@@ -30,9 +30,9 @@ | |||
30 | 30 | ||
31 | static | 31 | static |
32 | void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif, | 32 | void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif, |
33 | u8 band, struct ieee80211_tx_rate *rate) | 33 | u8 band, struct ieee80211_tx_rate *rate, u8 hlid) |
34 | { | 34 | { |
35 | u8 fw_rate = wl->fw_status->counters.tx_last_rate; | 35 | u8 fw_rate = wl->links[hlid].fw_rate_idx; |
36 | 36 | ||
37 | if (fw_rate > CONF_HW_RATE_INDEX_MAX) { | 37 | if (fw_rate > CONF_HW_RATE_INDEX_MAX) { |
38 | wl1271_error("last Tx rate invalid: %d", fw_rate); | 38 | wl1271_error("last Tx rate invalid: %d", fw_rate); |
@@ -79,6 +79,7 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) | |||
79 | struct sk_buff *skb; | 79 | struct sk_buff *skb; |
80 | int id = tx_stat_byte & WL18XX_TX_STATUS_DESC_ID_MASK; | 80 | int id = tx_stat_byte & WL18XX_TX_STATUS_DESC_ID_MASK; |
81 | bool tx_success; | 81 | bool tx_success; |
82 | struct wl1271_tx_hw_descr *tx_desc; | ||
82 | 83 | ||
83 | /* check for id legality */ | 84 | /* check for id legality */ |
84 | if (unlikely(id >= wl->num_tx_desc || wl->tx_frames[id] == NULL)) { | 85 | if (unlikely(id >= wl->num_tx_desc || wl->tx_frames[id] == NULL)) { |
@@ -91,6 +92,7 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) | |||
91 | 92 | ||
92 | skb = wl->tx_frames[id]; | 93 | skb = wl->tx_frames[id]; |
93 | info = IEEE80211_SKB_CB(skb); | 94 | info = IEEE80211_SKB_CB(skb); |
95 | tx_desc = (struct wl1271_tx_hw_descr *)skb->data; | ||
94 | 96 | ||
95 | if (wl12xx_is_dummy_packet(wl, skb)) { | 97 | if (wl12xx_is_dummy_packet(wl, skb)) { |
96 | wl1271_free_tx_id(wl, id); | 98 | wl1271_free_tx_id(wl, id); |
@@ -105,7 +107,9 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) | |||
105 | * the info->status structures | 107 | * the info->status structures |
106 | */ | 108 | */ |
107 | wl18xx_get_last_tx_rate(wl, info->control.vif, | 109 | wl18xx_get_last_tx_rate(wl, info->control.vif, |
108 | info->band, &info->status.rates[0]); | 110 | info->band, |
111 | &info->status.rates[0], | ||
112 | tx_desc->hlid); | ||
109 | 113 | ||
110 | info->status.rates[0].count = 1; /* no data about retries */ | 114 | info->status.rates[0].count = 1; /* no data about retries */ |
111 | info->status.ack_signal = -1; | 115 | info->status.ack_signal = -1; |
@@ -144,12 +148,22 @@ void wl18xx_tx_immediate_complete(struct wl1271 *wl) | |||
144 | struct wl18xx_fw_status_priv *status_priv = | 148 | struct wl18xx_fw_status_priv *status_priv = |
145 | (struct wl18xx_fw_status_priv *)wl->fw_status->priv; | 149 | (struct wl18xx_fw_status_priv *)wl->fw_status->priv; |
146 | struct wl18xx_priv *priv = wl->priv; | 150 | struct wl18xx_priv *priv = wl->priv; |
147 | u8 i; | 151 | u8 i, hlid; |
148 | 152 | ||
149 | /* nothing to do here */ | 153 | /* nothing to do here */ |
150 | if (priv->last_fw_rls_idx == status_priv->fw_release_idx) | 154 | if (priv->last_fw_rls_idx == status_priv->fw_release_idx) |
151 | return; | 155 | return; |
152 | 156 | ||
157 | /* update rates per link */ | ||
158 | hlid = wl->fw_status->counters.hlid; | ||
159 | |||
160 | if (hlid < WLCORE_MAX_LINKS) { | ||
161 | wl->links[hlid].fw_rate_idx = | ||
162 | wl->fw_status->counters.tx_last_rate; | ||
163 | wl->links[hlid].fw_rate_mbps = | ||
164 | wl->fw_status->counters.tx_last_rate_mbps; | ||
165 | } | ||
166 | |||
153 | /* freed Tx descriptors */ | 167 | /* freed Tx descriptors */ |
154 | wl1271_debug(DEBUG_TX, "last released desc = %d, current idx = %d", | 168 | wl1271_debug(DEBUG_TX, "last released desc = %d, current idx = %d", |
155 | priv->last_fw_rls_idx, status_priv->fw_release_idx); | 169 | priv->last_fw_rls_idx, status_priv->fw_release_idx); |
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h index 71e9e382ce80..5371cbdd54e0 100644 --- a/drivers/net/wireless/ti/wl18xx/wl18xx.h +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h | |||
@@ -29,7 +29,7 @@ | |||
29 | #define WL18XX_IFTYPE_VER 9 | 29 | #define WL18XX_IFTYPE_VER 9 |
30 | #define WL18XX_MAJOR_VER WLCORE_FW_VER_IGNORE | 30 | #define WL18XX_MAJOR_VER WLCORE_FW_VER_IGNORE |
31 | #define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE | 31 | #define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE |
32 | #define WL18XX_MINOR_VER 11 | 32 | #define WL18XX_MINOR_VER 58 |
33 | 33 | ||
34 | #define WL18XX_CMD_MAX_SIZE 740 | 34 | #define WL18XX_CMD_MAX_SIZE 740 |
35 | 35 | ||
@@ -125,7 +125,11 @@ struct wl18xx_fw_packet_counters { | |||
125 | /* Tx rate of the last transmitted packet */ | 125 | /* Tx rate of the last transmitted packet */ |
126 | u8 tx_last_rate; | 126 | u8 tx_last_rate; |
127 | 127 | ||
128 | u8 padding[2]; | 128 | /* Tx rate or Tx rate estimate pre-calculated by fw in mbps units */ |
129 | u8 tx_last_rate_mbps; | ||
130 | |||
131 | /* hlid for which the rates were reported */ | ||
132 | u8 hlid; | ||
129 | } __packed; | 133 | } __packed; |
130 | 134 | ||
131 | /* FW status registers */ | 135 | /* FW status registers */ |
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index 0d61fae88dcb..6321ed472891 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h | |||
@@ -105,6 +105,7 @@ enum wl12xx_role { | |||
105 | WL1271_ROLE_DEVICE, | 105 | WL1271_ROLE_DEVICE, |
106 | WL1271_ROLE_P2P_CL, | 106 | WL1271_ROLE_P2P_CL, |
107 | WL1271_ROLE_P2P_GO, | 107 | WL1271_ROLE_P2P_GO, |
108 | WL1271_ROLE_MESH_POINT, | ||
108 | 109 | ||
109 | WL12XX_INVALID_ROLE_TYPE = 0xff | 110 | WL12XX_INVALID_ROLE_TYPE = 0xff |
110 | }; | 111 | }; |
diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index 19b7ec7b69c2..f75d30444117 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c | |||
@@ -130,7 +130,7 @@ fail: | |||
130 | wl1271_error("Your WiFi FW version (%u.%u.%u.%u.%u) is invalid.\n" | 130 | wl1271_error("Your WiFi FW version (%u.%u.%u.%u.%u) is invalid.\n" |
131 | "Please use at least FW %s\n" | 131 | "Please use at least FW %s\n" |
132 | "You can get the latest firmwares at:\n" | 132 | "You can get the latest firmwares at:\n" |
133 | "git://github.com/TI-OpenLink/firmwares.git", | 133 | "git://git.ti.com/wilink8-wlan/wl18xx_fw.git", |
134 | fw_ver[FW_VER_CHIP], fw_ver[FW_VER_IF_TYPE], | 134 | fw_ver[FW_VER_CHIP], fw_ver[FW_VER_IF_TYPE], |
135 | fw_ver[FW_VER_MAJOR], fw_ver[FW_VER_SUBTYPE], | 135 | fw_ver[FW_VER_MAJOR], fw_ver[FW_VER_SUBTYPE], |
136 | fw_ver[FW_VER_MINOR], min_fw_str); | 136 | fw_ver[FW_VER_MINOR], min_fw_str); |
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 5f360cecbb0b..7f4da727bb7b 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c | |||
@@ -629,11 +629,14 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
629 | 629 | ||
630 | wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id); | 630 | wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id); |
631 | 631 | ||
632 | /* trying to use hidden SSID with an old hostapd version */ | 632 | /* If MESH --> ssid_len is always 0 */ |
633 | if (wlvif->ssid_len == 0 && !bss_conf->hidden_ssid) { | 633 | if (!ieee80211_vif_is_mesh(vif)) { |
634 | wl1271_error("got a null SSID from beacon/bss"); | 634 | /* trying to use hidden SSID with an old hostapd version */ |
635 | ret = -EINVAL; | 635 | if (wlvif->ssid_len == 0 && !bss_conf->hidden_ssid) { |
636 | goto out; | 636 | wl1271_error("got a null SSID from beacon/bss"); |
637 | ret = -EINVAL; | ||
638 | goto out; | ||
639 | } | ||
637 | } | 640 | } |
638 | 641 | ||
639 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | 642 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 9abc15293307..1d689169da76 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -221,6 +221,7 @@ static void wlcore_rc_update_work(struct work_struct *work) | |||
221 | struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif, | 221 | struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif, |
222 | rc_update_work); | 222 | rc_update_work); |
223 | struct wl1271 *wl = wlvif->wl; | 223 | struct wl1271 *wl = wlvif->wl; |
224 | struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); | ||
224 | 225 | ||
225 | mutex_lock(&wl->mutex); | 226 | mutex_lock(&wl->mutex); |
226 | 227 | ||
@@ -231,8 +232,16 @@ static void wlcore_rc_update_work(struct work_struct *work) | |||
231 | if (ret < 0) | 232 | if (ret < 0) |
232 | goto out; | 233 | goto out; |
233 | 234 | ||
234 | wlcore_hw_sta_rc_update(wl, wlvif); | 235 | if (ieee80211_vif_is_mesh(vif)) { |
236 | ret = wl1271_acx_set_ht_capabilities(wl, &wlvif->rc_ht_cap, | ||
237 | true, wlvif->sta.hlid); | ||
238 | if (ret < 0) | ||
239 | goto out_sleep; | ||
240 | } else { | ||
241 | wlcore_hw_sta_rc_update(wl, wlvif); | ||
242 | } | ||
235 | 243 | ||
244 | out_sleep: | ||
236 | wl1271_ps_elp_sleep(wl); | 245 | wl1271_ps_elp_sleep(wl); |
237 | out: | 246 | out: |
238 | mutex_unlock(&wl->mutex); | 247 | mutex_unlock(&wl->mutex); |
@@ -2153,10 +2162,14 @@ static void wlcore_free_klv_template(struct wl1271 *wl, u8 *idx) | |||
2153 | 2162 | ||
2154 | static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif) | 2163 | static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif) |
2155 | { | 2164 | { |
2165 | struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); | ||
2166 | |||
2156 | switch (wlvif->bss_type) { | 2167 | switch (wlvif->bss_type) { |
2157 | case BSS_TYPE_AP_BSS: | 2168 | case BSS_TYPE_AP_BSS: |
2158 | if (wlvif->p2p) | 2169 | if (wlvif->p2p) |
2159 | return WL1271_ROLE_P2P_GO; | 2170 | return WL1271_ROLE_P2P_GO; |
2171 | else if (ieee80211_vif_is_mesh(vif)) | ||
2172 | return WL1271_ROLE_MESH_POINT; | ||
2160 | else | 2173 | else |
2161 | return WL1271_ROLE_AP; | 2174 | return WL1271_ROLE_AP; |
2162 | 2175 | ||
@@ -2198,6 +2211,7 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) | |||
2198 | wlvif->p2p = 1; | 2211 | wlvif->p2p = 1; |
2199 | /* fall-through */ | 2212 | /* fall-through */ |
2200 | case NL80211_IFTYPE_AP: | 2213 | case NL80211_IFTYPE_AP: |
2214 | case NL80211_IFTYPE_MESH_POINT: | ||
2201 | wlvif->bss_type = BSS_TYPE_AP_BSS; | 2215 | wlvif->bss_type = BSS_TYPE_AP_BSS; |
2202 | break; | 2216 | break; |
2203 | default: | 2217 | default: |
@@ -4131,9 +4145,14 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, | |||
4131 | if (ret < 0) | 4145 | if (ret < 0) |
4132 | goto out; | 4146 | goto out; |
4133 | 4147 | ||
4134 | ret = wl1271_ap_set_probe_resp_tmpl(wl, wlvif->basic_rate, vif); | 4148 | /* No need to set probe resp template for mesh */ |
4135 | if (ret < 0) | 4149 | if (!ieee80211_vif_is_mesh(vif)) { |
4136 | goto out; | 4150 | ret = wl1271_ap_set_probe_resp_tmpl(wl, |
4151 | wlvif->basic_rate, | ||
4152 | vif); | ||
4153 | if (ret < 0) | ||
4154 | goto out; | ||
4155 | } | ||
4137 | 4156 | ||
4138 | ret = wlcore_set_beacon_template(wl, vif, true); | 4157 | ret = wlcore_set_beacon_template(wl, vif, true); |
4139 | if (ret < 0) | 4158 | if (ret < 0) |
@@ -4967,6 +4986,7 @@ static int wl12xx_sta_add(struct wl1271 *wl, | |||
4967 | return ret; | 4986 | return ret; |
4968 | 4987 | ||
4969 | wl_sta = (struct wl1271_station *)sta->drv_priv; | 4988 | wl_sta = (struct wl1271_station *)sta->drv_priv; |
4989 | wl_sta->wl = wl; | ||
4970 | hlid = wl_sta->hlid; | 4990 | hlid = wl_sta->hlid; |
4971 | 4991 | ||
4972 | ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid); | 4992 | ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid); |
@@ -5641,6 +5661,7 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw, | |||
5641 | 5661 | ||
5642 | /* this callback is atomic, so schedule a new work */ | 5662 | /* this callback is atomic, so schedule a new work */ |
5643 | wlvif->rc_update_bw = sta->bandwidth; | 5663 | wlvif->rc_update_bw = sta->bandwidth; |
5664 | memcpy(&wlvif->rc_ht_cap, &sta->ht_cap, sizeof(sta->ht_cap)); | ||
5644 | ieee80211_queue_work(hw, &wlvif->rc_update_work); | 5665 | ieee80211_queue_work(hw, &wlvif->rc_update_work); |
5645 | } | 5666 | } |
5646 | 5667 | ||
@@ -5679,6 +5700,16 @@ out: | |||
5679 | mutex_unlock(&wl->mutex); | 5700 | mutex_unlock(&wl->mutex); |
5680 | } | 5701 | } |
5681 | 5702 | ||
5703 | static u32 wlcore_op_get_expected_throughput(struct ieee80211_sta *sta) | ||
5704 | { | ||
5705 | struct wl1271_station *wl_sta = (struct wl1271_station *)sta->drv_priv; | ||
5706 | struct wl1271 *wl = wl_sta->wl; | ||
5707 | u8 hlid = wl_sta->hlid; | ||
5708 | |||
5709 | /* return in units of Kbps */ | ||
5710 | return (wl->links[hlid].fw_rate_mbps * 1000); | ||
5711 | } | ||
5712 | |||
5682 | static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) | 5713 | static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) |
5683 | { | 5714 | { |
5684 | struct wl1271 *wl = hw->priv; | 5715 | struct wl1271 *wl = hw->priv; |
@@ -5879,6 +5910,7 @@ static const struct ieee80211_ops wl1271_ops = { | |||
5879 | .switch_vif_chanctx = wlcore_op_switch_vif_chanctx, | 5910 | .switch_vif_chanctx = wlcore_op_switch_vif_chanctx, |
5880 | .sta_rc_update = wlcore_op_sta_rc_update, | 5911 | .sta_rc_update = wlcore_op_sta_rc_update, |
5881 | .sta_statistics = wlcore_op_sta_statistics, | 5912 | .sta_statistics = wlcore_op_sta_statistics, |
5913 | .get_expected_throughput = wlcore_op_get_expected_throughput, | ||
5882 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) | 5914 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) |
5883 | }; | 5915 | }; |
5884 | 5916 | ||
@@ -6062,7 +6094,11 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) | |||
6062 | BIT(NL80211_IFTYPE_AP) | | 6094 | BIT(NL80211_IFTYPE_AP) | |
6063 | BIT(NL80211_IFTYPE_P2P_DEVICE) | | 6095 | BIT(NL80211_IFTYPE_P2P_DEVICE) | |
6064 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | 6096 | BIT(NL80211_IFTYPE_P2P_CLIENT) | |
6097 | #ifdef CONFIG_MAC80211_MESH | ||
6098 | BIT(NL80211_IFTYPE_MESH_POINT) | | ||
6099 | #endif | ||
6065 | BIT(NL80211_IFTYPE_P2P_GO); | 6100 | BIT(NL80211_IFTYPE_P2P_GO); |
6101 | |||
6066 | wl->hw->wiphy->max_scan_ssids = 1; | 6102 | wl->hw->wiphy->max_scan_ssids = 1; |
6067 | wl->hw->wiphy->max_sched_scan_ssids = 16; | 6103 | wl->hw->wiphy->max_sched_scan_ssids = 16; |
6068 | wl->hw->wiphy->max_match_sets = 16; | 6104 | wl->hw->wiphy->max_match_sets = 16; |
diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c index c9bd294a0aa6..b9e14045195f 100644 --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c | |||
@@ -222,6 +222,13 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status) | |||
222 | enum wl_rx_buf_align rx_align; | 222 | enum wl_rx_buf_align rx_align; |
223 | int ret = 0; | 223 | int ret = 0; |
224 | 224 | ||
225 | /* update rates per link */ | ||
226 | hlid = status->counters.hlid; | ||
227 | |||
228 | if (hlid < WLCORE_MAX_LINKS) | ||
229 | wl->links[hlid].fw_rate_mbps = | ||
230 | status->counters.tx_last_rate_mbps; | ||
231 | |||
225 | while (drv_rx_counter != fw_rx_counter) { | 232 | while (drv_rx_counter != fw_rx_counter) { |
226 | buf_size = 0; | 233 | buf_size = 0; |
227 | rx_counter = drv_rx_counter; | 234 | rx_counter = drv_rx_counter; |
diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c index cea9443c22a6..6d24040889b8 100644 --- a/drivers/net/wireless/ti/wlcore/spi.c +++ b/drivers/net/wireless/ti/wlcore/spi.c | |||
@@ -70,16 +70,30 @@ | |||
70 | #define WSPI_MAX_CHUNK_SIZE 4092 | 70 | #define WSPI_MAX_CHUNK_SIZE 4092 |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * only support SPI for 12xx - this code should be reworked when 18xx | 73 | * wl18xx driver aggregation buffer size is (13 * PAGE_SIZE) compared to |
74 | * support is introduced | 74 | * (4 * PAGE_SIZE) for wl12xx, so use the larger buffer needed for wl18xx |
75 | */ | 75 | */ |
76 | #define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) | 76 | #define SPI_AGGR_BUFFER_SIZE (13 * PAGE_SIZE) |
77 | 77 | ||
78 | /* Maximum number of SPI write chunks */ | 78 | /* Maximum number of SPI write chunks */ |
79 | #define WSPI_MAX_NUM_OF_CHUNKS \ | 79 | #define WSPI_MAX_NUM_OF_CHUNKS \ |
80 | ((SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + 1) | 80 | ((SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + 1) |
81 | 81 | ||
82 | 82 | ||
83 | struct wilink_familiy_data { | ||
84 | char name[8]; | ||
85 | }; | ||
86 | |||
87 | const struct wilink_familiy_data *wilink_data; | ||
88 | |||
89 | static const struct wilink_familiy_data wl18xx_data = { | ||
90 | .name = "wl18xx", | ||
91 | }; | ||
92 | |||
93 | static const struct wilink_familiy_data wl12xx_data = { | ||
94 | .name = "wl12xx", | ||
95 | }; | ||
96 | |||
83 | struct wl12xx_spi_glue { | 97 | struct wl12xx_spi_glue { |
84 | struct device *dev; | 98 | struct device *dev; |
85 | struct platform_device *core; | 99 | struct platform_device *core; |
@@ -119,6 +133,7 @@ static void wl12xx_spi_init(struct device *child) | |||
119 | struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); | 133 | struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); |
120 | struct spi_transfer t; | 134 | struct spi_transfer t; |
121 | struct spi_message m; | 135 | struct spi_message m; |
136 | struct spi_device *spi = to_spi_device(glue->dev); | ||
122 | u8 *cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); | 137 | u8 *cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); |
123 | 138 | ||
124 | if (!cmd) { | 139 | if (!cmd) { |
@@ -151,6 +166,7 @@ static void wl12xx_spi_init(struct device *child) | |||
151 | cmd[6] |= WSPI_INIT_CMD_EN_FIXEDBUSY; | 166 | cmd[6] |= WSPI_INIT_CMD_EN_FIXEDBUSY; |
152 | 167 | ||
153 | cmd[7] = crc7_be(0, cmd+2, WSPI_INIT_CMD_CRC_LEN) | WSPI_INIT_CMD_END; | 168 | cmd[7] = crc7_be(0, cmd+2, WSPI_INIT_CMD_CRC_LEN) | WSPI_INIT_CMD_END; |
169 | |||
154 | /* | 170 | /* |
155 | * The above is the logical order; it must actually be stored | 171 | * The above is the logical order; it must actually be stored |
156 | * in the buffer byte-swapped. | 172 | * in the buffer byte-swapped. |
@@ -163,6 +179,28 @@ static void wl12xx_spi_init(struct device *child) | |||
163 | spi_message_add_tail(&t, &m); | 179 | spi_message_add_tail(&t, &m); |
164 | 180 | ||
165 | spi_sync(to_spi_device(glue->dev), &m); | 181 | spi_sync(to_spi_device(glue->dev), &m); |
182 | |||
183 | /* Send extra clocks with inverted CS (high). this is required | ||
184 | * by the wilink family in order to successfully enter WSPI mode. | ||
185 | */ | ||
186 | spi->mode ^= SPI_CS_HIGH; | ||
187 | memset(&m, 0, sizeof(m)); | ||
188 | spi_message_init(&m); | ||
189 | |||
190 | cmd[0] = 0xff; | ||
191 | cmd[1] = 0xff; | ||
192 | cmd[2] = 0xff; | ||
193 | cmd[3] = 0xff; | ||
194 | __swab32s((u32 *)cmd); | ||
195 | |||
196 | t.tx_buf = cmd; | ||
197 | t.len = 4; | ||
198 | spi_message_add_tail(&t, &m); | ||
199 | |||
200 | spi_sync(to_spi_device(glue->dev), &m); | ||
201 | |||
202 | /* Restore chip select configration to normal */ | ||
203 | spi->mode ^= SPI_CS_HIGH; | ||
166 | kfree(cmd); | 204 | kfree(cmd); |
167 | } | 205 | } |
168 | 206 | ||
@@ -270,22 +308,25 @@ static int __must_check wl12xx_spi_raw_read(struct device *child, int addr, | |||
270 | return 0; | 308 | return 0; |
271 | } | 309 | } |
272 | 310 | ||
273 | static int __must_check wl12xx_spi_raw_write(struct device *child, int addr, | 311 | static int __wl12xx_spi_raw_write(struct device *child, int addr, |
274 | void *buf, size_t len, bool fixed) | 312 | void *buf, size_t len, bool fixed) |
275 | { | 313 | { |
276 | struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); | 314 | struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); |
277 | /* SPI write buffers - 2 for each chunk */ | 315 | struct spi_transfer *t; |
278 | struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; | ||
279 | struct spi_message m; | 316 | struct spi_message m; |
280 | u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; /* 1 command per chunk */ | 317 | u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; /* 1 command per chunk */ |
281 | u32 *cmd; | 318 | u32 *cmd; |
282 | u32 chunk_len; | 319 | u32 chunk_len; |
283 | int i; | 320 | int i; |
284 | 321 | ||
322 | /* SPI write buffers - 2 for each chunk */ | ||
323 | t = kzalloc(sizeof(*t) * 2 * WSPI_MAX_NUM_OF_CHUNKS, GFP_KERNEL); | ||
324 | if (!t) | ||
325 | return -ENOMEM; | ||
326 | |||
285 | WARN_ON(len > SPI_AGGR_BUFFER_SIZE); | 327 | WARN_ON(len > SPI_AGGR_BUFFER_SIZE); |
286 | 328 | ||
287 | spi_message_init(&m); | 329 | spi_message_init(&m); |
288 | memset(t, 0, sizeof(t)); | ||
289 | 330 | ||
290 | cmd = &commands[0]; | 331 | cmd = &commands[0]; |
291 | i = 0; | 332 | i = 0; |
@@ -318,9 +359,26 @@ static int __must_check wl12xx_spi_raw_write(struct device *child, int addr, | |||
318 | 359 | ||
319 | spi_sync(to_spi_device(glue->dev), &m); | 360 | spi_sync(to_spi_device(glue->dev), &m); |
320 | 361 | ||
362 | kfree(t); | ||
321 | return 0; | 363 | return 0; |
322 | } | 364 | } |
323 | 365 | ||
366 | static int __must_check wl12xx_spi_raw_write(struct device *child, int addr, | ||
367 | void *buf, size_t len, bool fixed) | ||
368 | { | ||
369 | int ret; | ||
370 | |||
371 | /* The ELP wakeup write may fail the first time due to internal | ||
372 | * hardware latency. It is safer to send the wakeup command twice to | ||
373 | * avoid unexpected failures. | ||
374 | */ | ||
375 | if (addr == HW_ACCESS_ELP_CTRL_REG) | ||
376 | ret = __wl12xx_spi_raw_write(child, addr, buf, len, fixed); | ||
377 | ret = __wl12xx_spi_raw_write(child, addr, buf, len, fixed); | ||
378 | |||
379 | return ret; | ||
380 | } | ||
381 | |||
324 | /** | 382 | /** |
325 | * wl12xx_spi_set_power - power on/off the wl12xx unit | 383 | * wl12xx_spi_set_power - power on/off the wl12xx unit |
326 | * @child: wl12xx device handle. | 384 | * @child: wl12xx device handle. |
@@ -349,17 +407,38 @@ static int wl12xx_spi_set_power(struct device *child, bool enable) | |||
349 | return ret; | 407 | return ret; |
350 | } | 408 | } |
351 | 409 | ||
410 | /** | ||
411 | * wl12xx_spi_set_block_size | ||
412 | * | ||
413 | * This function is not needed for spi mode, but need to be present. | ||
414 | * Without it defined the wlcore fallback to use the wrong packet | ||
415 | * allignment on tx. | ||
416 | */ | ||
417 | static void wl12xx_spi_set_block_size(struct device *child, | ||
418 | unsigned int blksz) | ||
419 | { | ||
420 | } | ||
421 | |||
352 | static struct wl1271_if_operations spi_ops = { | 422 | static struct wl1271_if_operations spi_ops = { |
353 | .read = wl12xx_spi_raw_read, | 423 | .read = wl12xx_spi_raw_read, |
354 | .write = wl12xx_spi_raw_write, | 424 | .write = wl12xx_spi_raw_write, |
355 | .reset = wl12xx_spi_reset, | 425 | .reset = wl12xx_spi_reset, |
356 | .init = wl12xx_spi_init, | 426 | .init = wl12xx_spi_init, |
357 | .power = wl12xx_spi_set_power, | 427 | .power = wl12xx_spi_set_power, |
358 | .set_block_size = NULL, | 428 | .set_block_size = wl12xx_spi_set_block_size, |
359 | }; | 429 | }; |
360 | 430 | ||
361 | static const struct of_device_id wlcore_spi_of_match_table[] = { | 431 | static const struct of_device_id wlcore_spi_of_match_table[] = { |
362 | { .compatible = "ti,wl1271" }, | 432 | { .compatible = "ti,wl1271", .data = &wl12xx_data}, |
433 | { .compatible = "ti,wl1273", .data = &wl12xx_data}, | ||
434 | { .compatible = "ti,wl1281", .data = &wl12xx_data}, | ||
435 | { .compatible = "ti,wl1283", .data = &wl12xx_data}, | ||
436 | { .compatible = "ti,wl1801", .data = &wl18xx_data}, | ||
437 | { .compatible = "ti,wl1805", .data = &wl18xx_data}, | ||
438 | { .compatible = "ti,wl1807", .data = &wl18xx_data}, | ||
439 | { .compatible = "ti,wl1831", .data = &wl18xx_data}, | ||
440 | { .compatible = "ti,wl1835", .data = &wl18xx_data}, | ||
441 | { .compatible = "ti,wl1837", .data = &wl18xx_data}, | ||
363 | { } | 442 | { } |
364 | }; | 443 | }; |
365 | MODULE_DEVICE_TABLE(of, wlcore_spi_of_match_table); | 444 | MODULE_DEVICE_TABLE(of, wlcore_spi_of_match_table); |
@@ -375,18 +454,24 @@ static int wlcore_probe_of(struct spi_device *spi, struct wl12xx_spi_glue *glue, | |||
375 | struct wlcore_platdev_data *pdev_data) | 454 | struct wlcore_platdev_data *pdev_data) |
376 | { | 455 | { |
377 | struct device_node *dt_node = spi->dev.of_node; | 456 | struct device_node *dt_node = spi->dev.of_node; |
378 | int ret; | 457 | const struct of_device_id *of_id; |
458 | |||
459 | of_id = of_match_node(wlcore_spi_of_match_table, dt_node); | ||
460 | if (!of_id) | ||
461 | return -ENODEV; | ||
462 | |||
463 | wilink_data = of_id->data; | ||
464 | dev_info(&spi->dev, "selected chip familiy is %s\n", | ||
465 | wilink_data->name); | ||
379 | 466 | ||
380 | if (of_find_property(dt_node, "clock-xtal", NULL)) | 467 | if (of_find_property(dt_node, "clock-xtal", NULL)) |
381 | pdev_data->ref_clock_xtal = true; | 468 | pdev_data->ref_clock_xtal = true; |
382 | 469 | ||
383 | ret = of_property_read_u32(dt_node, "ref-clock-frequency", | 470 | /* optional clock frequency params */ |
384 | &pdev_data->ref_clock_freq); | 471 | of_property_read_u32(dt_node, "ref-clock-frequency", |
385 | if (ret) { | 472 | &pdev_data->ref_clock_freq); |
386 | dev_err(glue->dev, | 473 | of_property_read_u32(dt_node, "tcxo-clock-frequency", |
387 | "can't get reference clock frequency (%d)\n", ret); | 474 | &pdev_data->tcxo_clock_freq); |
388 | return ret; | ||
389 | } | ||
390 | 475 | ||
391 | return 0; | 476 | return 0; |
392 | } | 477 | } |
@@ -437,7 +522,8 @@ static int wl1271_probe(struct spi_device *spi) | |||
437 | return ret; | 522 | return ret; |
438 | } | 523 | } |
439 | 524 | ||
440 | glue->core = platform_device_alloc("wl12xx", PLATFORM_DEVID_AUTO); | 525 | glue->core = platform_device_alloc(wilink_data->name, |
526 | PLATFORM_DEVID_AUTO); | ||
441 | if (!glue->core) { | 527 | if (!glue->core) { |
442 | dev_err(glue->dev, "can't allocate platform_device\n"); | 528 | dev_err(glue->dev, "can't allocate platform_device\n"); |
443 | return -ENOMEM; | 529 | return -ENOMEM; |
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 5c4199f3a19a..242b4e37b94c 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h | |||
@@ -171,6 +171,12 @@ struct wl_fw_status { | |||
171 | 171 | ||
172 | /* Tx rate of the last transmitted packet */ | 172 | /* Tx rate of the last transmitted packet */ |
173 | u8 tx_last_rate; | 173 | u8 tx_last_rate; |
174 | |||
175 | /* Tx rate or Tx rate estimate pre calculated by fw in mbps */ | ||
176 | u8 tx_last_rate_mbps; | ||
177 | |||
178 | /* hlid for which the rates were reported */ | ||
179 | u8 hlid; | ||
174 | } counters; | 180 | } counters; |
175 | 181 | ||
176 | u32 log_start_addr; | 182 | u32 log_start_addr; |
@@ -273,6 +279,12 @@ struct wl1271_link { | |||
273 | /* bitmap of TIDs where RX BA sessions are active for this link */ | 279 | /* bitmap of TIDs where RX BA sessions are active for this link */ |
274 | u8 ba_bitmap; | 280 | u8 ba_bitmap; |
275 | 281 | ||
282 | /* the last fw rate index we used for this link */ | ||
283 | u8 fw_rate_idx; | ||
284 | |||
285 | /* the last fw rate [Mbps] we used for this link */ | ||
286 | u8 fw_rate_mbps; | ||
287 | |||
276 | /* The wlvif this link belongs to. Might be null for global links */ | 288 | /* The wlvif this link belongs to. Might be null for global links */ |
277 | struct wl12xx_vif *wlvif; | 289 | struct wl12xx_vif *wlvif; |
278 | 290 | ||
@@ -335,6 +347,7 @@ struct wl1271_station { | |||
335 | * Used in both AP and STA mode. | 347 | * Used in both AP and STA mode. |
336 | */ | 348 | */ |
337 | u64 total_freed_pkts; | 349 | u64 total_freed_pkts; |
350 | struct wl1271 *wl; | ||
338 | }; | 351 | }; |
339 | 352 | ||
340 | struct wl12xx_vif { | 353 | struct wl12xx_vif { |
@@ -472,6 +485,7 @@ struct wl12xx_vif { | |||
472 | 485 | ||
473 | /* update rate conrol */ | 486 | /* update rate conrol */ |
474 | enum ieee80211_sta_rx_bandwidth rc_update_bw; | 487 | enum ieee80211_sta_rx_bandwidth rc_update_bw; |
488 | struct ieee80211_sta_ht_cap rc_ht_cap; | ||
475 | struct work_struct rc_update_work; | 489 | struct work_struct rc_update_work; |
476 | 490 | ||
477 | /* | 491 | /* |
diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index e66153d60bd5..76860a461ed2 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h | |||
@@ -40,6 +40,7 @@ struct ath9k_platform_data { | |||
40 | bool tx_gain_buffalo; | 40 | bool tx_gain_buffalo; |
41 | bool disable_2ghz; | 41 | bool disable_2ghz; |
42 | bool disable_5ghz; | 42 | bool disable_5ghz; |
43 | bool led_active_high; | ||
43 | 44 | ||
44 | int (*get_mac_revision)(void); | 45 | int (*get_mac_revision)(void); |
45 | int (*external_reset)(void); | 46 | int (*external_reset)(void); |
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index a5ac2cad5cb7..b20e3d56253f 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h | |||
@@ -504,6 +504,9 @@ | |||
504 | #define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000 | 504 | #define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000 |
505 | #define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT 20 | 505 | #define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT 20 |
506 | 506 | ||
507 | #define BCMA_CCB_MII_MNG_CTL 0x0000 | ||
508 | #define BCMA_CCB_MII_MNG_CMD_DATA 0x0004 | ||
509 | |||
507 | /* BCM4331 ChipControl numbers. */ | 510 | /* BCM4331 ChipControl numbers. */ |
508 | #define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */ | 511 | #define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */ |
509 | #define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */ | 512 | #define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */ |