aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ti
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ti')
-rw-r--r--drivers/net/wireless/ti/wilink_platform_data.c37
-rw-r--r--drivers/net/wireless/ti/wl1251/cmd.c2
-rw-r--r--drivers/net/wireless/ti/wl1251/sdio.c31
-rw-r--r--drivers/net/wireless/ti/wl1251/spi.c71
-rw-r--r--drivers/net/wireless/ti/wl1251/wl1251.h4
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c67
-rw-r--r--drivers/net/wireless/ti/wl12xx/wl12xx.h53
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c85
-rw-r--r--drivers/net/wireless/ti/wl18xx/tx.c4
-rw-r--r--drivers/net/wireless/ti/wl18xx/wl18xx.h62
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.c7
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.h6
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c24
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.h9
-rw-r--r--drivers/net/wireless/ti/wlcore/event.c4
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h9
-rw-r--r--drivers/net/wireless/ti/wlcore/init.c6
-rw-r--r--drivers/net/wireless/ti/wlcore/io.h8
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c200
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.c6
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.c19
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.h2
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c4
-rw-r--r--drivers/net/wireless/ti/wlcore/sysfs.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c45
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.h1
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h27
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h86
28 files changed, 630 insertions, 251 deletions
diff --git a/drivers/net/wireless/ti/wilink_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c
index 998e95895f9d..a92bd3e89796 100644
--- a/drivers/net/wireless/ti/wilink_platform_data.c
+++ b/drivers/net/wireless/ti/wilink_platform_data.c
@@ -23,17 +23,17 @@
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/wl12xx.h> 24#include <linux/wl12xx.h>
25 25
26static struct wl12xx_platform_data *platform_data; 26static struct wl12xx_platform_data *wl12xx_platform_data;
27 27
28int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data) 28int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
29{ 29{
30 if (platform_data) 30 if (wl12xx_platform_data)
31 return -EBUSY; 31 return -EBUSY;
32 if (!data) 32 if (!data)
33 return -EINVAL; 33 return -EINVAL;
34 34
35 platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); 35 wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
36 if (!platform_data) 36 if (!wl12xx_platform_data)
37 return -ENOMEM; 37 return -ENOMEM;
38 38
39 return 0; 39 return 0;
@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
41 41
42struct wl12xx_platform_data *wl12xx_get_platform_data(void) 42struct wl12xx_platform_data *wl12xx_get_platform_data(void)
43{ 43{
44 if (!platform_data) 44 if (!wl12xx_platform_data)
45 return ERR_PTR(-ENODEV); 45 return ERR_PTR(-ENODEV);
46 46
47 return platform_data; 47 return wl12xx_platform_data;
48} 48}
49EXPORT_SYMBOL(wl12xx_get_platform_data); 49EXPORT_SYMBOL(wl12xx_get_platform_data);
50
51static struct wl1251_platform_data *wl1251_platform_data;
52
53int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
54{
55 if (wl1251_platform_data)
56 return -EBUSY;
57 if (!data)
58 return -EINVAL;
59
60 wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
61 if (!wl1251_platform_data)
62 return -ENOMEM;
63
64 return 0;
65}
66
67struct wl1251_platform_data *wl1251_get_platform_data(void)
68{
69 if (!wl1251_platform_data)
70 return ERR_PTR(-ENODEV);
71
72 return wl1251_platform_data;
73}
74EXPORT_SYMBOL(wl1251_get_platform_data);
diff --git a/drivers/net/wireless/ti/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c
index 223649bcaa5a..bf1fa18b9786 100644
--- a/drivers/net/wireless/ti/wl1251/cmd.c
+++ b/drivers/net/wireless/ti/wl1251/cmd.c
@@ -448,7 +448,7 @@ int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
448 * Note: This bug may be caused by the fw's DTIM handling. 448 * Note: This bug may be caused by the fw's DTIM handling.
449 */ 449 */
450 if (is_zero_ether_addr(wl->bssid)) 450 if (is_zero_ether_addr(wl->bssid))
451 cmd->params.scan_options |= WL1251_SCAN_OPT_PRIORITY_HIGH; 451 cmd->params.scan_options |= cpu_to_le16(WL1251_SCAN_OPT_PRIORITY_HIGH);
452 cmd->params.num_channels = n_channels; 452 cmd->params.num_channels = n_channels;
453 cmd->params.num_probe_requests = n_probes; 453 cmd->params.num_probe_requests = n_probes;
454 cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */ 454 cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index e2b3d9c541e8..b661f896e9fe 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -28,6 +28,7 @@
28#include <linux/wl12xx.h> 28#include <linux/wl12xx.h>
29#include <linux/irq.h> 29#include <linux/irq.h>
30#include <linux/pm_runtime.h> 30#include <linux/pm_runtime.h>
31#include <linux/gpio.h>
31 32
32#include "wl1251.h" 33#include "wl1251.h"
33 34
@@ -182,8 +183,9 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
182 * callback in case it wants to do any additional setup, 183 * callback in case it wants to do any additional setup,
183 * for example enabling clock buffer for the module. 184 * for example enabling clock buffer for the module.
184 */ 185 */
185 if (wl->set_power) 186 if (gpio_is_valid(wl->power_gpio))
186 wl->set_power(true); 187 gpio_set_value(wl->power_gpio, true);
188
187 189
188 ret = pm_runtime_get_sync(&func->dev); 190 ret = pm_runtime_get_sync(&func->dev);
189 if (ret < 0) { 191 if (ret < 0) {
@@ -203,8 +205,8 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
203 if (ret < 0) 205 if (ret < 0)
204 goto out; 206 goto out;
205 207
206 if (wl->set_power) 208 if (gpio_is_valid(wl->power_gpio))
207 wl->set_power(false); 209 gpio_set_value(wl->power_gpio, false);
208 } 210 }
209 211
210out: 212out:
@@ -227,7 +229,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
227 struct wl1251 *wl; 229 struct wl1251 *wl;
228 struct ieee80211_hw *hw; 230 struct ieee80211_hw *hw;
229 struct wl1251_sdio *wl_sdio; 231 struct wl1251_sdio *wl_sdio;
230 const struct wl12xx_platform_data *wl12xx_board_data; 232 const struct wl1251_platform_data *wl1251_board_data;
231 233
232 hw = wl1251_alloc_hw(); 234 hw = wl1251_alloc_hw();
233 if (IS_ERR(hw)) 235 if (IS_ERR(hw))
@@ -254,11 +256,20 @@ static int wl1251_sdio_probe(struct sdio_func *func,
254 wl->if_priv = wl_sdio; 256 wl->if_priv = wl_sdio;
255 wl->if_ops = &wl1251_sdio_ops; 257 wl->if_ops = &wl1251_sdio_ops;
256 258
257 wl12xx_board_data = wl12xx_get_platform_data(); 259 wl1251_board_data = wl1251_get_platform_data();
258 if (!IS_ERR(wl12xx_board_data)) { 260 if (!IS_ERR(wl1251_board_data)) {
259 wl->set_power = wl12xx_board_data->set_power; 261 wl->power_gpio = wl1251_board_data->power_gpio;
260 wl->irq = wl12xx_board_data->irq; 262 wl->irq = wl1251_board_data->irq;
261 wl->use_eeprom = wl12xx_board_data->use_eeprom; 263 wl->use_eeprom = wl1251_board_data->use_eeprom;
264 }
265
266 if (gpio_is_valid(wl->power_gpio)) {
267 ret = devm_gpio_request(&func->dev, wl->power_gpio,
268 "wl1251 power");
269 if (ret) {
270 wl1251_error("Failed to request gpio: %d\n", ret);
271 goto disable;
272 }
262 } 273 }
263 274
264 if (wl->irq) { 275 if (wl->irq) {
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 1342f81e683d..b06d36d99362 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -26,6 +26,10 @@
26#include <linux/crc7.h> 26#include <linux/crc7.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/wl12xx.h> 28#include <linux/wl12xx.h>
29#include <linux/gpio.h>
30#include <linux/of.h>
31#include <linux/of_gpio.h>
32#include <linux/regulator/consumer.h>
29 33
30#include "wl1251.h" 34#include "wl1251.h"
31#include "reg.h" 35#include "reg.h"
@@ -221,8 +225,8 @@ static void wl1251_spi_disable_irq(struct wl1251 *wl)
221 225
222static int wl1251_spi_set_power(struct wl1251 *wl, bool enable) 226static int wl1251_spi_set_power(struct wl1251 *wl, bool enable)
223{ 227{
224 if (wl->set_power) 228 if (gpio_is_valid(wl->power_gpio))
225 wl->set_power(enable); 229 gpio_set_value(wl->power_gpio, enable);
226 230
227 return 0; 231 return 0;
228} 232}
@@ -238,13 +242,13 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
238 242
239static int wl1251_spi_probe(struct spi_device *spi) 243static int wl1251_spi_probe(struct spi_device *spi)
240{ 244{
241 struct wl12xx_platform_data *pdata; 245 struct wl1251_platform_data *pdata = dev_get_platdata(&spi->dev);
246 struct device_node *np = spi->dev.of_node;
242 struct ieee80211_hw *hw; 247 struct ieee80211_hw *hw;
243 struct wl1251 *wl; 248 struct wl1251 *wl;
244 int ret; 249 int ret;
245 250
246 pdata = dev_get_platdata(&spi->dev); 251 if (!np && !pdata) {
247 if (!pdata) {
248 wl1251_error("no platform data"); 252 wl1251_error("no platform data");
249 return -ENODEV; 253 return -ENODEV;
250 } 254 }
@@ -271,22 +275,42 @@ static int wl1251_spi_probe(struct spi_device *spi)
271 goto out_free; 275 goto out_free;
272 } 276 }
273 277
274 wl->set_power = pdata->set_power; 278 if (np) {
275 if (!wl->set_power) { 279 wl->use_eeprom = of_property_read_bool(np, "ti,wl1251-has-eeprom");
276 wl1251_error("set power function missing in platform data"); 280 wl->power_gpio = of_get_named_gpio(np, "ti,power-gpio", 0);
277 return -ENODEV; 281 } else if (pdata) {
282 wl->power_gpio = pdata->power_gpio;
283 wl->use_eeprom = pdata->use_eeprom;
284 }
285
286 if (wl->power_gpio == -EPROBE_DEFER) {
287 ret = -EPROBE_DEFER;
288 goto out_free;
289 }
290
291 if (gpio_is_valid(wl->power_gpio)) {
292 ret = devm_gpio_request_one(&spi->dev, wl->power_gpio,
293 GPIOF_OUT_INIT_LOW, "wl1251 power");
294 if (ret) {
295 wl1251_error("Failed to request gpio: %d\n", ret);
296 goto out_free;
297 }
298 } else {
299 wl1251_error("set power gpio missing in platform data");
300 ret = -ENODEV;
301 goto out_free;
278 } 302 }
279 303
280 wl->irq = spi->irq; 304 wl->irq = spi->irq;
281 if (wl->irq < 0) { 305 if (wl->irq < 0) {
282 wl1251_error("irq missing in platform data"); 306 wl1251_error("irq missing in platform data");
283 return -ENODEV; 307 ret = -ENODEV;
308 goto out_free;
284 } 309 }
285 310
286 wl->use_eeprom = pdata->use_eeprom;
287
288 irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); 311 irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
289 ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); 312 ret = devm_request_irq(&spi->dev, wl->irq, wl1251_irq, 0,
313 DRIVER_NAME, wl);
290 if (ret < 0) { 314 if (ret < 0) {
291 wl1251_error("request_irq() failed: %d", ret); 315 wl1251_error("request_irq() failed: %d", ret);
292 goto out_free; 316 goto out_free;
@@ -294,16 +318,26 @@ static int wl1251_spi_probe(struct spi_device *spi)
294 318
295 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); 319 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
296 320
321 wl->vio = devm_regulator_get(&spi->dev, "vio");
322 if (IS_ERR(wl->vio)) {
323 ret = PTR_ERR(wl->vio);
324 wl1251_error("vio regulator missing: %d", ret);
325 goto out_free;
326 }
327
328 ret = regulator_enable(wl->vio);
329 if (ret)
330 goto out_free;
331
297 ret = wl1251_init_ieee80211(wl); 332 ret = wl1251_init_ieee80211(wl);
298 if (ret) 333 if (ret)
299 goto out_irq; 334 goto disable_regulator;
300 335
301 return 0; 336 return 0;
302 337
303 out_irq: 338disable_regulator:
304 free_irq(wl->irq, wl); 339 regulator_disable(wl->vio);
305 340out_free:
306 out_free:
307 ieee80211_free_hw(hw); 341 ieee80211_free_hw(hw);
308 342
309 return ret; 343 return ret;
@@ -315,6 +349,7 @@ static int wl1251_spi_remove(struct spi_device *spi)
315 349
316 free_irq(wl->irq, wl); 350 free_irq(wl->irq, wl);
317 wl1251_free_hw(wl); 351 wl1251_free_hw(wl);
352 regulator_disable(wl->vio);
318 353
319 return 0; 354 return 0;
320} 355}
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index 235617a7716d..16dae5269175 100644
--- a/drivers/net/wireless/ti/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
@@ -276,10 +276,12 @@ struct wl1251 {
276 void *if_priv; 276 void *if_priv;
277 const struct wl1251_if_operations *if_ops; 277 const struct wl1251_if_operations *if_ops;
278 278
279 void (*set_power)(bool enable); 279 int power_gpio;
280 int irq; 280 int irq;
281 bool use_eeprom; 281 bool use_eeprom;
282 282
283 struct regulator *vio;
284
283 spinlock_t wl_lock; 285 spinlock_t wl_lock;
284 286
285 enum wl1251_state state; 287 enum wl1251_state state;
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index be7129ba16ad..d50dfac91631 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -1378,7 +1378,7 @@ static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
1378 1378
1379static int wl12xx_tx_delayed_compl(struct wl1271 *wl) 1379static int wl12xx_tx_delayed_compl(struct wl1271 *wl)
1380{ 1380{
1381 if (wl->fw_status_1->tx_results_counter == 1381 if (wl->fw_status->tx_results_counter ==
1382 (wl->tx_results_count & 0xff)) 1382 (wl->tx_results_count & 0xff))
1383 return 0; 1383 return 0;
1384 1384
@@ -1438,6 +1438,37 @@ out:
1438 return ret; 1438 return ret;
1439} 1439}
1440 1440
1441static void wl12xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
1442 struct wl_fw_status *fw_status)
1443{
1444 struct wl12xx_fw_status *int_fw_status = raw_fw_status;
1445
1446 fw_status->intr = le32_to_cpu(int_fw_status->intr);
1447 fw_status->fw_rx_counter = int_fw_status->fw_rx_counter;
1448 fw_status->drv_rx_counter = int_fw_status->drv_rx_counter;
1449 fw_status->tx_results_counter = int_fw_status->tx_results_counter;
1450 fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs;
1451
1452 fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime);
1453 fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap);
1454 fw_status->link_fast_bitmap =
1455 le32_to_cpu(int_fw_status->link_fast_bitmap);
1456 fw_status->total_released_blks =
1457 le32_to_cpu(int_fw_status->total_released_blks);
1458 fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total);
1459
1460 fw_status->counters.tx_released_pkts =
1461 int_fw_status->counters.tx_released_pkts;
1462 fw_status->counters.tx_lnk_free_pkts =
1463 int_fw_status->counters.tx_lnk_free_pkts;
1464 fw_status->counters.tx_voice_released_blks =
1465 int_fw_status->counters.tx_voice_released_blks;
1466 fw_status->counters.tx_last_rate =
1467 int_fw_status->counters.tx_last_rate;
1468
1469 fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr);
1470}
1471
1441static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl, 1472static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1442 struct wl12xx_vif *wlvif) 1473 struct wl12xx_vif *wlvif)
1443{ 1474{
@@ -1677,6 +1708,7 @@ static struct wlcore_ops wl12xx_ops = {
1677 .tx_delayed_compl = wl12xx_tx_delayed_compl, 1708 .tx_delayed_compl = wl12xx_tx_delayed_compl,
1678 .hw_init = wl12xx_hw_init, 1709 .hw_init = wl12xx_hw_init,
1679 .init_vif = NULL, 1710 .init_vif = NULL,
1711 .convert_fw_status = wl12xx_convert_fw_status,
1680 .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask, 1712 .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask,
1681 .get_pg_ver = wl12xx_get_pg_ver, 1713 .get_pg_ver = wl12xx_get_pg_ver,
1682 .get_mac = wl12xx_get_mac, 1714 .get_mac = wl12xx_get_mac,
@@ -1711,22 +1743,53 @@ static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
1711 }, 1743 },
1712}; 1744};
1713 1745
1746static const struct ieee80211_iface_limit wl12xx_iface_limits[] = {
1747 {
1748 .max = 3,
1749 .types = BIT(NL80211_IFTYPE_STATION),
1750 },
1751 {
1752 .max = 1,
1753 .types = BIT(NL80211_IFTYPE_AP) |
1754 BIT(NL80211_IFTYPE_P2P_GO) |
1755 BIT(NL80211_IFTYPE_P2P_CLIENT),
1756 },
1757};
1758
1759static const struct ieee80211_iface_combination
1760wl12xx_iface_combinations[] = {
1761 {
1762 .max_interfaces = 3,
1763 .limits = wl12xx_iface_limits,
1764 .n_limits = ARRAY_SIZE(wl12xx_iface_limits),
1765 .num_different_channels = 1,
1766 },
1767};
1768
1714static int wl12xx_setup(struct wl1271 *wl) 1769static int wl12xx_setup(struct wl1271 *wl)
1715{ 1770{
1716 struct wl12xx_priv *priv = wl->priv; 1771 struct wl12xx_priv *priv = wl->priv;
1717 struct wlcore_platdev_data *pdev_data = dev_get_platdata(&wl->pdev->dev); 1772 struct wlcore_platdev_data *pdev_data = dev_get_platdata(&wl->pdev->dev);
1718 struct wl12xx_platform_data *pdata = pdev_data->pdata; 1773 struct wl12xx_platform_data *pdata = pdev_data->pdata;
1719 1774
1775 BUILD_BUG_ON(WL12XX_MAX_LINKS > WLCORE_MAX_LINKS);
1776 BUILD_BUG_ON(WL12XX_MAX_AP_STATIONS > WL12XX_MAX_LINKS);
1777
1720 wl->rtable = wl12xx_rtable; 1778 wl->rtable = wl12xx_rtable;
1721 wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS; 1779 wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
1722 wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS; 1780 wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
1723 wl->num_channels = 1; 1781 wl->num_links = WL12XX_MAX_LINKS;
1782 wl->max_ap_stations = WL12XX_MAX_AP_STATIONS;
1783 wl->iface_combinations = wl12xx_iface_combinations;
1784 wl->n_iface_combinations = ARRAY_SIZE(wl12xx_iface_combinations);
1724 wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES; 1785 wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
1725 wl->band_rate_to_idx = wl12xx_band_rate_to_idx; 1786 wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
1726 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; 1787 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
1727 wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; 1788 wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
1789 wl->fw_status_len = sizeof(struct wl12xx_fw_status);
1728 wl->fw_status_priv_len = 0; 1790 wl->fw_status_priv_len = 0;
1729 wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics); 1791 wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics);
1792 wl->ofdm_only_ap = true;
1730 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap); 1793 wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap);
1731 wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap); 1794 wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
1732 wl12xx_conf_init(wl); 1795 wl12xx_conf_init(wl);
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h
index 9e5484a73667..75c92658bfea 100644
--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
@@ -65,6 +65,9 @@
65 65
66#define WL12XX_RX_BA_MAX_SESSIONS 3 66#define WL12XX_RX_BA_MAX_SESSIONS 3
67 67
68#define WL12XX_MAX_AP_STATIONS 8
69#define WL12XX_MAX_LINKS 12
70
68struct wl127x_rx_mem_pool_addr { 71struct wl127x_rx_mem_pool_addr {
69 u32 addr; 72 u32 addr;
70 u32 addr_extra; 73 u32 addr_extra;
@@ -79,4 +82,54 @@ struct wl12xx_priv {
79 struct wl127x_rx_mem_pool_addr *rx_mem_addr; 82 struct wl127x_rx_mem_pool_addr *rx_mem_addr;
80}; 83};
81 84
85struct wl12xx_fw_packet_counters {
86 /* Cumulative counter of released packets per AC */
87 u8 tx_released_pkts[NUM_TX_QUEUES];
88
89 /* Cumulative counter of freed packets per HLID */
90 u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
91
92 /* Cumulative counter of released Voice memory blocks */
93 u8 tx_voice_released_blks;
94
95 /* Tx rate of the last transmitted packet */
96 u8 tx_last_rate;
97
98 u8 padding[2];
99} __packed;
100
101/* FW status registers */
102struct wl12xx_fw_status {
103 __le32 intr;
104 u8 fw_rx_counter;
105 u8 drv_rx_counter;
106 u8 reserved;
107 u8 tx_results_counter;
108 __le32 rx_pkt_descs[WL12XX_NUM_RX_DESCRIPTORS];
109
110 __le32 fw_localtime;
111
112 /*
113 * A bitmap (where each bit represents a single HLID)
114 * to indicate if the station is in PS mode.
115 */
116 __le32 link_ps_bitmap;
117
118 /*
119 * A bitmap (where each bit represents a single HLID) to indicate
120 * if the station is in Fast mode
121 */
122 __le32 link_fast_bitmap;
123
124 /* Cumulative counter of total released mem blocks since FW-reset */
125 __le32 total_released_blks;
126
127 /* Size (in Memory Blocks) of TX pool */
128 __le32 tx_total;
129
130 struct wl12xx_fw_packet_counters counters;
131
132 __le32 log_start_addr;
133} __packed;
134
82#endif /* __WL12XX_PRIV_H__ */ 135#endif /* __WL12XX_PRIV_H__ */
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index ec37b16585df..de5b4fa5d166 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -648,7 +648,7 @@ static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = {
648}; 648};
649 649
650/* TODO: maybe move to a new header file? */ 650/* TODO: maybe move to a new header file? */
651#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-2.bin" 651#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-3.bin"
652 652
653static int wl18xx_identify_chip(struct wl1271 *wl) 653static int wl18xx_identify_chip(struct wl1271 *wl)
654{ 654{
@@ -1133,6 +1133,39 @@ static int wl18xx_hw_init(struct wl1271 *wl)
1133 return ret; 1133 return ret;
1134} 1134}
1135 1135
1136static void wl18xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
1137 struct wl_fw_status *fw_status)
1138{
1139 struct wl18xx_fw_status *int_fw_status = raw_fw_status;
1140
1141 fw_status->intr = le32_to_cpu(int_fw_status->intr);
1142 fw_status->fw_rx_counter = int_fw_status->fw_rx_counter;
1143 fw_status->drv_rx_counter = int_fw_status->drv_rx_counter;
1144 fw_status->tx_results_counter = int_fw_status->tx_results_counter;
1145 fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs;
1146
1147 fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime);
1148 fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap);
1149 fw_status->link_fast_bitmap =
1150 le32_to_cpu(int_fw_status->link_fast_bitmap);
1151 fw_status->total_released_blks =
1152 le32_to_cpu(int_fw_status->total_released_blks);
1153 fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total);
1154
1155 fw_status->counters.tx_released_pkts =
1156 int_fw_status->counters.tx_released_pkts;
1157 fw_status->counters.tx_lnk_free_pkts =
1158 int_fw_status->counters.tx_lnk_free_pkts;
1159 fw_status->counters.tx_voice_released_blks =
1160 int_fw_status->counters.tx_voice_released_blks;
1161 fw_status->counters.tx_last_rate =
1162 int_fw_status->counters.tx_last_rate;
1163
1164 fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr);
1165
1166 fw_status->priv = &int_fw_status->priv;
1167}
1168
1136static void wl18xx_set_tx_desc_csum(struct wl1271 *wl, 1169static void wl18xx_set_tx_desc_csum(struct wl1271 *wl,
1137 struct wl1271_tx_hw_descr *desc, 1170 struct wl1271_tx_hw_descr *desc,
1138 struct sk_buff *skb) 1171 struct sk_buff *skb)
@@ -1572,7 +1605,7 @@ static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1572{ 1605{
1573 u8 thold; 1606 u8 thold;
1574 struct wl18xx_fw_status_priv *status_priv = 1607 struct wl18xx_fw_status_priv *status_priv =
1575 (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv; 1608 (struct wl18xx_fw_status_priv *)wl->fw_status->priv;
1576 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap); 1609 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1577 1610
1578 /* suspended links are never high priority */ 1611 /* suspended links are never high priority */
@@ -1594,7 +1627,7 @@ static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1594{ 1627{
1595 u8 thold; 1628 u8 thold;
1596 struct wl18xx_fw_status_priv *status_priv = 1629 struct wl18xx_fw_status_priv *status_priv =
1597 (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv; 1630 (struct wl18xx_fw_status_priv *)wl->fw_status->priv;
1598 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap); 1631 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1599 1632
1600 if (test_bit(hlid, (unsigned long *)&suspend_bitmap)) 1633 if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
@@ -1632,6 +1665,7 @@ static struct wlcore_ops wl18xx_ops = {
1632 .tx_immediate_compl = wl18xx_tx_immediate_completion, 1665 .tx_immediate_compl = wl18xx_tx_immediate_completion,
1633 .tx_delayed_compl = NULL, 1666 .tx_delayed_compl = NULL,
1634 .hw_init = wl18xx_hw_init, 1667 .hw_init = wl18xx_hw_init,
1668 .convert_fw_status = wl18xx_convert_fw_status,
1635 .set_tx_desc_csum = wl18xx_set_tx_desc_csum, 1669 .set_tx_desc_csum = wl18xx_set_tx_desc_csum,
1636 .get_pg_ver = wl18xx_get_pg_ver, 1670 .get_pg_ver = wl18xx_get_pg_ver,
1637 .set_rx_csum = wl18xx_set_rx_csum, 1671 .set_rx_csum = wl18xx_set_rx_csum,
@@ -1713,19 +1747,62 @@ static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
1713 }, 1747 },
1714}; 1748};
1715 1749
1750static const struct ieee80211_iface_limit wl18xx_iface_limits[] = {
1751 {
1752 .max = 3,
1753 .types = BIT(NL80211_IFTYPE_STATION),
1754 },
1755 {
1756 .max = 1,
1757 .types = BIT(NL80211_IFTYPE_AP) |
1758 BIT(NL80211_IFTYPE_P2P_GO) |
1759 BIT(NL80211_IFTYPE_P2P_CLIENT),
1760 },
1761};
1762
1763static const struct ieee80211_iface_limit wl18xx_iface_ap_limits[] = {
1764 {
1765 .max = 2,
1766 .types = BIT(NL80211_IFTYPE_AP),
1767 },
1768};
1769
1770static const struct ieee80211_iface_combination
1771wl18xx_iface_combinations[] = {
1772 {
1773 .max_interfaces = 3,
1774 .limits = wl18xx_iface_limits,
1775 .n_limits = ARRAY_SIZE(wl18xx_iface_limits),
1776 .num_different_channels = 2,
1777 },
1778 {
1779 .max_interfaces = 2,
1780 .limits = wl18xx_iface_ap_limits,
1781 .n_limits = ARRAY_SIZE(wl18xx_iface_ap_limits),
1782 .num_different_channels = 1,
1783 }
1784};
1785
1716static int wl18xx_setup(struct wl1271 *wl) 1786static int wl18xx_setup(struct wl1271 *wl)
1717{ 1787{
1718 struct wl18xx_priv *priv = wl->priv; 1788 struct wl18xx_priv *priv = wl->priv;
1719 int ret; 1789 int ret;
1720 1790
1791 BUILD_BUG_ON(WL18XX_MAX_LINKS > WLCORE_MAX_LINKS);
1792 BUILD_BUG_ON(WL18XX_MAX_AP_STATIONS > WL18XX_MAX_LINKS);
1793
1721 wl->rtable = wl18xx_rtable; 1794 wl->rtable = wl18xx_rtable;
1722 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS; 1795 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
1723 wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS; 1796 wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
1724 wl->num_channels = 2; 1797 wl->num_links = WL18XX_MAX_LINKS;
1798 wl->max_ap_stations = WL18XX_MAX_AP_STATIONS;
1799 wl->iface_combinations = wl18xx_iface_combinations;
1800 wl->n_iface_combinations = ARRAY_SIZE(wl18xx_iface_combinations);
1725 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES; 1801 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
1726 wl->band_rate_to_idx = wl18xx_band_rate_to_idx; 1802 wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
1727 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; 1803 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
1728 wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; 1804 wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
1805 wl->fw_status_len = sizeof(struct wl18xx_fw_status);
1729 wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv); 1806 wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv);
1730 wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics); 1807 wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics);
1731 wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv); 1808 wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv);
diff --git a/drivers/net/wireless/ti/wl18xx/tx.c b/drivers/net/wireless/ti/wl18xx/tx.c
index 57c694396647..be1ebd55ac88 100644
--- a/drivers/net/wireless/ti/wl18xx/tx.c
+++ b/drivers/net/wireless/ti/wl18xx/tx.c
@@ -32,7 +32,7 @@ static
32void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif, 32void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif,
33 struct ieee80211_tx_rate *rate) 33 struct ieee80211_tx_rate *rate)
34{ 34{
35 u8 fw_rate = wl->fw_status_2->counters.tx_last_rate; 35 u8 fw_rate = wl->fw_status->counters.tx_last_rate;
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);
@@ -139,7 +139,7 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
139void wl18xx_tx_immediate_complete(struct wl1271 *wl) 139void wl18xx_tx_immediate_complete(struct wl1271 *wl)
140{ 140{
141 struct wl18xx_fw_status_priv *status_priv = 141 struct wl18xx_fw_status_priv *status_priv =
142 (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv; 142 (struct wl18xx_fw_status_priv *)wl->fw_status->priv;
143 struct wl18xx_priv *priv = wl->priv; 143 struct wl18xx_priv *priv = wl->priv;
144 u8 i; 144 u8 i;
145 145
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h
index 9204e07ee432..eb7cfe817010 100644
--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
@@ -26,10 +26,10 @@
26 26
27/* minimum FW required for driver */ 27/* minimum FW required for driver */
28#define WL18XX_CHIP_VER 8 28#define WL18XX_CHIP_VER 8
29#define WL18XX_IFTYPE_VER 5 29#define WL18XX_IFTYPE_VER 8
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 39 32#define WL18XX_MINOR_VER 13
33 33
34#define WL18XX_CMD_MAX_SIZE 740 34#define WL18XX_CMD_MAX_SIZE 740
35 35
@@ -40,7 +40,10 @@
40 40
41#define WL18XX_NUM_MAC_ADDRESSES 3 41#define WL18XX_NUM_MAC_ADDRESSES 3
42 42
43#define WL18XX_RX_BA_MAX_SESSIONS 5 43#define WL18XX_RX_BA_MAX_SESSIONS 13
44
45#define WL18XX_MAX_AP_STATIONS 10
46#define WL18XX_MAX_LINKS 16
44 47
45struct wl18xx_priv { 48struct wl18xx_priv {
46 /* buffer for sending commands to FW */ 49 /* buffer for sending commands to FW */
@@ -109,6 +112,59 @@ struct wl18xx_fw_status_priv {
109 u8 padding[3]; 112 u8 padding[3];
110}; 113};
111 114
115struct wl18xx_fw_packet_counters {
116 /* Cumulative counter of released packets per AC */
117 u8 tx_released_pkts[NUM_TX_QUEUES];
118
119 /* Cumulative counter of freed packets per HLID */
120 u8 tx_lnk_free_pkts[WL18XX_MAX_LINKS];
121
122 /* Cumulative counter of released Voice memory blocks */
123 u8 tx_voice_released_blks;
124
125 /* Tx rate of the last transmitted packet */
126 u8 tx_last_rate;
127
128 u8 padding[2];
129} __packed;
130
131/* FW status registers */
132struct wl18xx_fw_status {
133 __le32 intr;
134 u8 fw_rx_counter;
135 u8 drv_rx_counter;
136 u8 reserved;
137 u8 tx_results_counter;
138 __le32 rx_pkt_descs[WL18XX_NUM_RX_DESCRIPTORS];
139
140 __le32 fw_localtime;
141
142 /*
143 * A bitmap (where each bit represents a single HLID)
144 * to indicate if the station is in PS mode.
145 */
146 __le32 link_ps_bitmap;
147
148 /*
149 * A bitmap (where each bit represents a single HLID) to indicate
150 * if the station is in Fast mode
151 */
152 __le32 link_fast_bitmap;
153
154 /* Cumulative counter of total released mem blocks since FW-reset */
155 __le32 total_released_blks;
156
157 /* Size (in Memory Blocks) of TX pool */
158 __le32 tx_total;
159
160 struct wl18xx_fw_packet_counters counters;
161
162 __le32 log_start_addr;
163
164 /* Private status to be used by the lower drivers */
165 struct wl18xx_fw_status_priv priv;
166} __packed;
167
112#define WL18XX_PHY_VERSION_MAX_LEN 20 168#define WL18XX_PHY_VERSION_MAX_LEN 20
113 169
114struct wl18xx_static_data_priv { 170struct wl18xx_static_data_priv {
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index ec83675a2446..b924ceadc02c 100644
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -358,7 +358,8 @@ int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, struct wl12xx_vif *wlvif,
358 struct acx_beacon_filter_option *beacon_filter = NULL; 358 struct acx_beacon_filter_option *beacon_filter = NULL;
359 int ret = 0; 359 int ret = 0;
360 360
361 wl1271_debug(DEBUG_ACX, "acx beacon filter opt"); 361 wl1271_debug(DEBUG_ACX, "acx beacon filter opt enable=%d",
362 enable_filter);
362 363
363 if (enable_filter && 364 if (enable_filter &&
364 wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED) 365 wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED)
@@ -1591,7 +1592,8 @@ out:
1591 return ret; 1592 return ret;
1592} 1593}
1593 1594
1594int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr) 1595int wl1271_acx_set_inconnection_sta(struct wl1271 *wl,
1596 struct wl12xx_vif *wlvif, u8 *addr)
1595{ 1597{
1596 struct wl1271_acx_inconnection_sta *acx = NULL; 1598 struct wl1271_acx_inconnection_sta *acx = NULL;
1597 int ret; 1599 int ret;
@@ -1603,6 +1605,7 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr)
1603 return -ENOMEM; 1605 return -ENOMEM;
1604 1606
1605 memcpy(acx->addr, addr, ETH_ALEN); 1607 memcpy(acx->addr, addr, ETH_ALEN);
1608 acx->role_id = wlvif->role_id;
1606 1609
1607 ret = wl1271_cmd_configure(wl, ACX_UPDATE_INCONNECTION_STA_LIST, 1610 ret = wl1271_cmd_configure(wl, ACX_UPDATE_INCONNECTION_STA_LIST,
1608 acx, sizeof(*acx)); 1611 acx, sizeof(*acx));
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
index 6dcfad9b0472..954d57ec98f4 100644
--- a/drivers/net/wireless/ti/wlcore/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -824,7 +824,8 @@ struct wl1271_acx_inconnection_sta {
824 struct acx_header header; 824 struct acx_header header;
825 825
826 u8 addr[ETH_ALEN]; 826 u8 addr[ETH_ALEN];
827 u8 padding1[2]; 827 u8 role_id;
828 u8 padding;
828} __packed; 829} __packed;
829 830
830/* 831/*
@@ -1118,7 +1119,8 @@ int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1118 bool enable); 1119 bool enable);
1119int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif); 1120int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif);
1120int wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif); 1121int wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif);
1121int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); 1122int wl1271_acx_set_inconnection_sta(struct wl1271 *wl,
1123 struct wl12xx_vif *wlvif, u8 *addr);
1122int wl1271_acx_fm_coex(struct wl1271 *wl); 1124int wl1271_acx_fm_coex(struct wl1271 *wl);
1123int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl); 1125int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
1124int wl12xx_acx_config_hangover(struct wl1271 *wl); 1126int wl12xx_acx_config_hangover(struct wl1271 *wl);
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 9b2ecf52449f..40dc30f4faaa 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -60,8 +60,8 @@ static int __wlcore_cmd_send(struct wl1271 *wl, u16 id, void *buf,
60 u16 status; 60 u16 status;
61 u16 poll_count = 0; 61 u16 poll_count = 0;
62 62
63 if (WARN_ON(wl->state == WLCORE_STATE_RESTARTING && 63 if (unlikely(wl->state == WLCORE_STATE_RESTARTING &&
64 id != CMD_STOP_FWLOGGER)) 64 id != CMD_STOP_FWLOGGER))
65 return -EIO; 65 return -EIO;
66 66
67 cmd = buf; 67 cmd = buf;
@@ -312,8 +312,8 @@ static int wlcore_get_new_session_id(struct wl1271 *wl, u8 hlid)
312int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) 312int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
313{ 313{
314 unsigned long flags; 314 unsigned long flags;
315 u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); 315 u8 link = find_first_zero_bit(wl->links_map, wl->num_links);
316 if (link >= WL12XX_MAX_LINKS) 316 if (link >= wl->num_links)
317 return -EBUSY; 317 return -EBUSY;
318 318
319 wl->session_ids[link] = wlcore_get_new_session_id(wl, link); 319 wl->session_ids[link] = wlcore_get_new_session_id(wl, link);
@@ -324,9 +324,14 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
324 __set_bit(link, wlvif->links_map); 324 __set_bit(link, wlvif->links_map);
325 spin_unlock_irqrestore(&wl->wl_lock, flags); 325 spin_unlock_irqrestore(&wl->wl_lock, flags);
326 326
327 /* take the last "freed packets" value from the current FW status */ 327 /*
328 wl->links[link].prev_freed_pkts = 328 * take the last "freed packets" value from the current FW status.
329 wl->fw_status_2->counters.tx_lnk_free_pkts[link]; 329 * on recovery, we might not have fw_status yet, and
330 * tx_lnk_free_pkts will be NULL. check for it.
331 */
332 if (wl->fw_status->counters.tx_lnk_free_pkts)
333 wl->links[link].prev_freed_pkts =
334 wl->fw_status->counters.tx_lnk_free_pkts[link];
330 wl->links[link].wlvif = wlvif; 335 wl->links[link].wlvif = wlvif;
331 336
332 /* 337 /*
@@ -1527,6 +1532,7 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1527 cmd->sp_len = sta->max_sp; 1532 cmd->sp_len = sta->max_sp;
1528 cmd->wmm = sta->wme ? 1 : 0; 1533 cmd->wmm = sta->wme ? 1 : 0;
1529 cmd->session_id = wl->session_ids[hlid]; 1534 cmd->session_id = wl->session_ids[hlid];
1535 cmd->role_id = wlvif->role_id;
1530 1536
1531 for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++) 1537 for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++)
1532 if (sta->wme && (sta->uapsd_queues & BIT(i))) 1538 if (sta->wme && (sta->uapsd_queues & BIT(i)))
@@ -1563,7 +1569,8 @@ out:
1563 return ret; 1569 return ret;
1564} 1570}
1565 1571
1566int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid) 1572int wl12xx_cmd_remove_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1573 u8 hlid)
1567{ 1574{
1568 struct wl12xx_cmd_remove_peer *cmd; 1575 struct wl12xx_cmd_remove_peer *cmd;
1569 int ret; 1576 int ret;
@@ -1581,6 +1588,7 @@ int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid)
1581 /* We never send a deauth, mac80211 is in charge of this */ 1588 /* We never send a deauth, mac80211 is in charge of this */
1582 cmd->reason_opcode = 0; 1589 cmd->reason_opcode = 0;
1583 cmd->send_deauth_flag = 0; 1590 cmd->send_deauth_flag = 0;
1591 cmd->role_id = wlvif->role_id;
1584 1592
1585 ret = wl1271_cmd_send(wl, CMD_REMOVE_PEER, cmd, sizeof(*cmd), 0); 1593 ret = wl1271_cmd_send(wl, CMD_REMOVE_PEER, cmd, sizeof(*cmd), 0);
1586 if (ret < 0) { 1594 if (ret < 0) {
diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h
index 323d4a856e4b..b084830a61cf 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.h
+++ b/drivers/net/wireless/ti/wlcore/cmd.h
@@ -88,7 +88,8 @@ int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id,
88int wl12xx_croc(struct wl1271 *wl, u8 role_id); 88int wl12xx_croc(struct wl1271 *wl, u8 role_id);
89int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, 89int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
90 struct ieee80211_sta *sta, u8 hlid); 90 struct ieee80211_sta *sta, u8 hlid);
91int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid); 91int wl12xx_cmd_remove_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
92 u8 hlid);
92void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel, 93void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel,
93 enum ieee80211_band band); 94 enum ieee80211_band band);
94int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl); 95int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl);
@@ -206,7 +207,7 @@ enum cmd_templ {
206#define WL1271_COMMAND_TIMEOUT 2000 207#define WL1271_COMMAND_TIMEOUT 2000
207#define WL1271_CMD_TEMPL_DFLT_SIZE 252 208#define WL1271_CMD_TEMPL_DFLT_SIZE 252
208#define WL1271_CMD_TEMPL_MAX_SIZE 512 209#define WL1271_CMD_TEMPL_MAX_SIZE 512
209#define WL1271_EVENT_TIMEOUT 1500 210#define WL1271_EVENT_TIMEOUT 5000
210 211
211struct wl1271_cmd_header { 212struct wl1271_cmd_header {
212 __le16 id; 213 __le16 id;
@@ -594,6 +595,8 @@ struct wl12xx_cmd_add_peer {
594 u8 sp_len; 595 u8 sp_len;
595 u8 wmm; 596 u8 wmm;
596 u8 session_id; 597 u8 session_id;
598 u8 role_id;
599 u8 padding[3];
597} __packed; 600} __packed;
598 601
599struct wl12xx_cmd_remove_peer { 602struct wl12xx_cmd_remove_peer {
@@ -602,7 +605,7 @@ struct wl12xx_cmd_remove_peer {
602 u8 hlid; 605 u8 hlid;
603 u8 reason_opcode; 606 u8 reason_opcode;
604 u8 send_deauth_flag; 607 u8 send_deauth_flag;
605 u8 padding1; 608 u8 role_id;
606} __packed; 609} __packed;
607 610
608/* 611/*
diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c
index 8d3b34965db3..1f9a36031b06 100644
--- a/drivers/net/wireless/ti/wlcore/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -67,7 +67,7 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif)
67 u8 hlid; 67 u8 hlid;
68 struct wl1271_link *lnk; 68 struct wl1271_link *lnk;
69 for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, 69 for_each_set_bit(hlid, wlvif->ap.sta_hlid_map,
70 WL12XX_MAX_LINKS) { 70 wl->num_links) {
71 lnk = &wl->links[hlid]; 71 lnk = &wl->links[hlid];
72 if (!lnk->ba_bitmap) 72 if (!lnk->ba_bitmap)
73 continue; 73 continue;
@@ -172,7 +172,7 @@ static void wlcore_disconnect_sta(struct wl1271 *wl, unsigned long sta_bitmap)
172 const u8 *addr; 172 const u8 *addr;
173 int h; 173 int h;
174 174
175 for_each_set_bit(h, &sta_bitmap, WL12XX_MAX_LINKS) { 175 for_each_set_bit(h, &sta_bitmap, wl->num_links) {
176 bool found = false; 176 bool found = false;
177 /* find the ap vif connected to this sta */ 177 /* find the ap vif connected to this sta */
178 wl12xx_for_each_wlvif_ap(wl, wlvif) { 178 wl12xx_for_each_wlvif_ap(wl, wlvif) {
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
index 51f8d634d32f..1555ff970050 100644
--- a/drivers/net/wireless/ti/wlcore/hw_ops.h
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -106,6 +106,15 @@ wlcore_hw_init_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
106 return 0; 106 return 0;
107} 107}
108 108
109static inline void
110wlcore_hw_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
111 struct wl_fw_status *fw_status)
112{
113 BUG_ON(!wl->ops->convert_fw_status);
114
115 wl->ops->convert_fw_status(wl, raw_fw_status, fw_status);
116}
117
109static inline u32 118static inline u32
110wlcore_hw_sta_get_ap_rate_mask(struct wl1271 *wl, struct wl12xx_vif *wlvif) 119wlcore_hw_sta_get_ap_rate_mask(struct wl1271 *wl, struct wl12xx_vif *wlvif)
111{ 120{
diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c
index 7699f9d07e26..199e94120864 100644
--- a/drivers/net/wireless/ti/wlcore/init.c
+++ b/drivers/net/wireless/ti/wlcore/init.c
@@ -287,8 +287,8 @@ static int wl1271_init_sta_beacon_filter(struct wl1271 *wl,
287 if (ret < 0) 287 if (ret < 0)
288 return ret; 288 return ret;
289 289
290 /* enable beacon filtering */ 290 /* disable beacon filtering until we get the first beacon */
291 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true); 291 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
292 if (ret < 0) 292 if (ret < 0)
293 return ret; 293 return ret;
294 294
@@ -462,7 +462,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif)
462 * If the basic rates contain OFDM rates, use OFDM only 462 * If the basic rates contain OFDM rates, use OFDM only
463 * rates for unicast TX as well. Else use all supported rates. 463 * rates for unicast TX as well. Else use all supported rates.
464 */ 464 */
465 if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES)) 465 if (wl->ofdm_only_ap && (wlvif->basic_rate_set & CONF_TX_OFDM_RATES))
466 supported_rates = CONF_TX_OFDM_RATES; 466 supported_rates = CONF_TX_OFDM_RATES;
467 else 467 else
468 supported_rates = CONF_TX_ENABLED_RATES; 468 supported_rates = CONF_TX_ENABLED_RATES;
diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h
index 07e3d6a049ad..0305729d0986 100644
--- a/drivers/net/wireless/ti/wlcore/io.h
+++ b/drivers/net/wireless/ti/wlcore/io.h
@@ -60,7 +60,9 @@ static inline int __must_check wlcore_raw_write(struct wl1271 *wl, int addr,
60{ 60{
61 int ret; 61 int ret;
62 62
63 if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags)) 63 if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags) ||
64 WARN_ON((test_bit(WL1271_FLAG_IN_ELP, &wl->flags) &&
65 addr != HW_ACCESS_ELP_CTRL_REG)))
64 return -EIO; 66 return -EIO;
65 67
66 ret = wl->if_ops->write(wl->dev, addr, buf, len, fixed); 68 ret = wl->if_ops->write(wl->dev, addr, buf, len, fixed);
@@ -76,7 +78,9 @@ static inline int __must_check wlcore_raw_read(struct wl1271 *wl, int addr,
76{ 78{
77 int ret; 79 int ret;
78 80
79 if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags)) 81 if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags) ||
82 WARN_ON((test_bit(WL1271_FLAG_IN_ELP, &wl->flags) &&
83 addr != HW_ACCESS_ELP_CTRL_REG)))
80 return -EIO; 84 return -EIO;
81 85
82 ret = wl->if_ops->read(wl->dev, addr, buf, len, fixed); 86 ret = wl->if_ops->read(wl->dev, addr, buf, len, fixed);
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index b46b3116cc55..ed88d3913483 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -345,24 +345,24 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
345 * Start high-level PS if the STA is asleep with enough blocks in FW. 345 * Start high-level PS if the STA is asleep with enough blocks in FW.
346 * Make an exception if this is the only connected link. In this 346 * Make an exception if this is the only connected link. In this
347 * case FW-memory congestion is less of a problem. 347 * case FW-memory congestion is less of a problem.
348 * Note that a single connected STA means 3 active links, since we must 348 * Note that a single connected STA means 2*ap_count + 1 active links,
349 * account for the global and broadcast AP links. The "fw_ps" check 349 * since we must account for the global and broadcast AP links
350 * assures us the third link is a STA connected to the AP. Otherwise 350 * for each AP. The "fw_ps" check assures us the other link is a STA
351 * the FW would not set the PSM bit. 351 * connected to the AP. Otherwise the FW would not set the PSM bit.
352 */ 352 */
353 else if (wl->active_link_count > 3 && fw_ps && 353 else if (wl->active_link_count > (wl->ap_count*2 + 1) && fw_ps &&
354 tx_pkts >= WL1271_PS_STA_MAX_PACKETS) 354 tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
355 wl12xx_ps_link_start(wl, wlvif, hlid, true); 355 wl12xx_ps_link_start(wl, wlvif, hlid, true);
356} 356}
357 357
358static void wl12xx_irq_update_links_status(struct wl1271 *wl, 358static void wl12xx_irq_update_links_status(struct wl1271 *wl,
359 struct wl12xx_vif *wlvif, 359 struct wl12xx_vif *wlvif,
360 struct wl_fw_status_2 *status) 360 struct wl_fw_status *status)
361{ 361{
362 u32 cur_fw_ps_map; 362 u32 cur_fw_ps_map;
363 u8 hlid; 363 u8 hlid;
364 364
365 cur_fw_ps_map = le32_to_cpu(status->link_ps_bitmap); 365 cur_fw_ps_map = status->link_ps_bitmap;
366 if (wl->ap_fw_ps_map != cur_fw_ps_map) { 366 if (wl->ap_fw_ps_map != cur_fw_ps_map) {
367 wl1271_debug(DEBUG_PSM, 367 wl1271_debug(DEBUG_PSM,
368 "link ps prev 0x%x cur 0x%x changed 0x%x", 368 "link ps prev 0x%x cur 0x%x changed 0x%x",
@@ -372,77 +372,73 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
372 wl->ap_fw_ps_map = cur_fw_ps_map; 372 wl->ap_fw_ps_map = cur_fw_ps_map;
373 } 373 }
374 374
375 for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS) 375 for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, wl->num_links)
376 wl12xx_irq_ps_regulate_link(wl, wlvif, hlid, 376 wl12xx_irq_ps_regulate_link(wl, wlvif, hlid,
377 wl->links[hlid].allocated_pkts); 377 wl->links[hlid].allocated_pkts);
378} 378}
379 379
380static int wlcore_fw_status(struct wl1271 *wl, 380static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status)
381 struct wl_fw_status_1 *status_1,
382 struct wl_fw_status_2 *status_2)
383{ 381{
384 struct wl12xx_vif *wlvif; 382 struct wl12xx_vif *wlvif;
385 struct timespec ts; 383 struct timespec ts;
386 u32 old_tx_blk_count = wl->tx_blocks_available; 384 u32 old_tx_blk_count = wl->tx_blocks_available;
387 int avail, freed_blocks; 385 int avail, freed_blocks;
388 int i; 386 int i;
389 size_t status_len;
390 int ret; 387 int ret;
391 struct wl1271_link *lnk; 388 struct wl1271_link *lnk;
392 389
393 status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + 390 ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR,
394 sizeof(*status_2) + wl->fw_status_priv_len; 391 wl->raw_fw_status,
395 392 wl->fw_status_len, false);
396 ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1,
397 status_len, false);
398 if (ret < 0) 393 if (ret < 0)
399 return ret; 394 return ret;
400 395
396 wlcore_hw_convert_fw_status(wl, wl->raw_fw_status, wl->fw_status);
397
401 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " 398 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
402 "drv_rx_counter = %d, tx_results_counter = %d)", 399 "drv_rx_counter = %d, tx_results_counter = %d)",
403 status_1->intr, 400 status->intr,
404 status_1->fw_rx_counter, 401 status->fw_rx_counter,
405 status_1->drv_rx_counter, 402 status->drv_rx_counter,
406 status_1->tx_results_counter); 403 status->tx_results_counter);
407 404
408 for (i = 0; i < NUM_TX_QUEUES; i++) { 405 for (i = 0; i < NUM_TX_QUEUES; i++) {
409 /* prevent wrap-around in freed-packets counter */ 406 /* prevent wrap-around in freed-packets counter */
410 wl->tx_allocated_pkts[i] -= 407 wl->tx_allocated_pkts[i] -=
411 (status_2->counters.tx_released_pkts[i] - 408 (status->counters.tx_released_pkts[i] -
412 wl->tx_pkts_freed[i]) & 0xff; 409 wl->tx_pkts_freed[i]) & 0xff;
413 410
414 wl->tx_pkts_freed[i] = status_2->counters.tx_released_pkts[i]; 411 wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i];
415 } 412 }
416 413
417 414
418 for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) { 415 for_each_set_bit(i, wl->links_map, wl->num_links) {
419 u8 diff; 416 u8 diff;
420 lnk = &wl->links[i]; 417 lnk = &wl->links[i];
421 418
422 /* prevent wrap-around in freed-packets counter */ 419 /* prevent wrap-around in freed-packets counter */
423 diff = (status_2->counters.tx_lnk_free_pkts[i] - 420 diff = (status->counters.tx_lnk_free_pkts[i] -
424 lnk->prev_freed_pkts) & 0xff; 421 lnk->prev_freed_pkts) & 0xff;
425 422
426 if (diff == 0) 423 if (diff == 0)
427 continue; 424 continue;
428 425
429 lnk->allocated_pkts -= diff; 426 lnk->allocated_pkts -= diff;
430 lnk->prev_freed_pkts = status_2->counters.tx_lnk_free_pkts[i]; 427 lnk->prev_freed_pkts = status->counters.tx_lnk_free_pkts[i];
431 428
432 /* accumulate the prev_freed_pkts counter */ 429 /* accumulate the prev_freed_pkts counter */
433 lnk->total_freed_pkts += diff; 430 lnk->total_freed_pkts += diff;
434 } 431 }
435 432
436 /* prevent wrap-around in total blocks counter */ 433 /* prevent wrap-around in total blocks counter */
437 if (likely(wl->tx_blocks_freed <= 434 if (likely(wl->tx_blocks_freed <= status->total_released_blks))
438 le32_to_cpu(status_2->total_released_blks))) 435 freed_blocks = status->total_released_blks -
439 freed_blocks = le32_to_cpu(status_2->total_released_blks) -
440 wl->tx_blocks_freed; 436 wl->tx_blocks_freed;
441 else 437 else
442 freed_blocks = 0x100000000LL - wl->tx_blocks_freed + 438 freed_blocks = 0x100000000LL - wl->tx_blocks_freed +
443 le32_to_cpu(status_2->total_released_blks); 439 status->total_released_blks;
444 440
445 wl->tx_blocks_freed = le32_to_cpu(status_2->total_released_blks); 441 wl->tx_blocks_freed = status->total_released_blks;
446 442
447 wl->tx_allocated_blocks -= freed_blocks; 443 wl->tx_allocated_blocks -= freed_blocks;
448 444
@@ -458,7 +454,7 @@ static int wlcore_fw_status(struct wl1271 *wl,
458 cancel_delayed_work(&wl->tx_watchdog_work); 454 cancel_delayed_work(&wl->tx_watchdog_work);
459 } 455 }
460 456
461 avail = le32_to_cpu(status_2->tx_total) - wl->tx_allocated_blocks; 457 avail = status->tx_total - wl->tx_allocated_blocks;
462 458
463 /* 459 /*
464 * The FW might change the total number of TX memblocks before 460 * The FW might change the total number of TX memblocks before
@@ -477,15 +473,15 @@ static int wlcore_fw_status(struct wl1271 *wl,
477 473
478 /* for AP update num of allocated TX blocks per link and ps status */ 474 /* for AP update num of allocated TX blocks per link and ps status */
479 wl12xx_for_each_wlvif_ap(wl, wlvif) { 475 wl12xx_for_each_wlvif_ap(wl, wlvif) {
480 wl12xx_irq_update_links_status(wl, wlvif, status_2); 476 wl12xx_irq_update_links_status(wl, wlvif, status);
481 } 477 }
482 478
483 /* update the host-chipset time offset */ 479 /* update the host-chipset time offset */
484 getnstimeofday(&ts); 480 getnstimeofday(&ts);
485 wl->time_offset = (timespec_to_ns(&ts) >> 10) - 481 wl->time_offset = (timespec_to_ns(&ts) >> 10) -
486 (s64)le32_to_cpu(status_2->fw_localtime); 482 (s64)(status->fw_localtime);
487 483
488 wl->fw_fast_lnk_map = le32_to_cpu(status_2->link_fast_bitmap); 484 wl->fw_fast_lnk_map = status->link_fast_bitmap;
489 485
490 return 0; 486 return 0;
491} 487}
@@ -549,13 +545,13 @@ static int wlcore_irq_locked(struct wl1271 *wl)
549 clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); 545 clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
550 smp_mb__after_clear_bit(); 546 smp_mb__after_clear_bit();
551 547
552 ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2); 548 ret = wlcore_fw_status(wl, wl->fw_status);
553 if (ret < 0) 549 if (ret < 0)
554 goto out; 550 goto out;
555 551
556 wlcore_hw_tx_immediate_compl(wl); 552 wlcore_hw_tx_immediate_compl(wl);
557 553
558 intr = le32_to_cpu(wl->fw_status_1->intr); 554 intr = wl->fw_status->intr;
559 intr &= WLCORE_ALL_INTR_MASK; 555 intr &= WLCORE_ALL_INTR_MASK;
560 if (!intr) { 556 if (!intr) {
561 done = true; 557 done = true;
@@ -584,7 +580,7 @@ static int wlcore_irq_locked(struct wl1271 *wl)
584 if (likely(intr & WL1271_ACX_INTR_DATA)) { 580 if (likely(intr & WL1271_ACX_INTR_DATA)) {
585 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); 581 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
586 582
587 ret = wlcore_rx(wl, wl->fw_status_1); 583 ret = wlcore_rx(wl, wl->fw_status);
588 if (ret < 0) 584 if (ret < 0)
589 goto out; 585 goto out;
590 586
@@ -786,10 +782,11 @@ out:
786 782
787void wl12xx_queue_recovery_work(struct wl1271 *wl) 783void wl12xx_queue_recovery_work(struct wl1271 *wl)
788{ 784{
789 WARN_ON(!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags));
790
791 /* Avoid a recursive recovery */ 785 /* Avoid a recursive recovery */
792 if (wl->state == WLCORE_STATE_ON) { 786 if (wl->state == WLCORE_STATE_ON) {
787 WARN_ON(!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY,
788 &wl->flags));
789
793 wl->state = WLCORE_STATE_RESTARTING; 790 wl->state = WLCORE_STATE_RESTARTING;
794 set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); 791 set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
795 wl1271_ps_elp_wakeup(wl); 792 wl1271_ps_elp_wakeup(wl);
@@ -803,7 +800,7 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
803 size_t len; 800 size_t len;
804 801
805 /* Make sure we have enough room */ 802 /* Make sure we have enough room */
806 len = min(maxlen, (size_t)(PAGE_SIZE - wl->fwlog_size)); 803 len = min_t(size_t, maxlen, PAGE_SIZE - wl->fwlog_size);
807 804
808 /* Fill the FW log file, consumed by the sysfs fwlog entry */ 805 /* Fill the FW log file, consumed by the sysfs fwlog entry */
809 memcpy(wl->fwlog + wl->fwlog_size, memblock, len); 806 memcpy(wl->fwlog + wl->fwlog_size, memblock, len);
@@ -843,11 +840,11 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
843 wl12xx_cmd_stop_fwlog(wl); 840 wl12xx_cmd_stop_fwlog(wl);
844 841
845 /* Read the first memory block address */ 842 /* Read the first memory block address */
846 ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2); 843 ret = wlcore_fw_status(wl, wl->fw_status);
847 if (ret < 0) 844 if (ret < 0)
848 goto out; 845 goto out;
849 846
850 addr = le32_to_cpu(wl->fw_status_2->log_start_addr); 847 addr = wl->fw_status->log_start_addr;
851 if (!addr) 848 if (!addr)
852 goto out; 849 goto out;
853 850
@@ -990,23 +987,23 @@ static int wlcore_fw_wakeup(struct wl1271 *wl)
990 987
991static int wl1271_setup(struct wl1271 *wl) 988static int wl1271_setup(struct wl1271 *wl)
992{ 989{
993 wl->fw_status_1 = kzalloc(WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + 990 wl->raw_fw_status = kzalloc(wl->fw_status_len, GFP_KERNEL);
994 sizeof(*wl->fw_status_2) + 991 if (!wl->raw_fw_status)
995 wl->fw_status_priv_len, GFP_KERNEL); 992 goto err;
996 if (!wl->fw_status_1)
997 return -ENOMEM;
998 993
999 wl->fw_status_2 = (struct wl_fw_status_2 *) 994 wl->fw_status = kzalloc(sizeof(*wl->fw_status), GFP_KERNEL);
1000 (((u8 *) wl->fw_status_1) + 995 if (!wl->fw_status)
1001 WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc)); 996 goto err;
1002 997
1003 wl->tx_res_if = kzalloc(sizeof(*wl->tx_res_if), GFP_KERNEL); 998 wl->tx_res_if = kzalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
1004 if (!wl->tx_res_if) { 999 if (!wl->tx_res_if)
1005 kfree(wl->fw_status_1); 1000 goto err;
1006 return -ENOMEM;
1007 }
1008 1001
1009 return 0; 1002 return 0;
1003err:
1004 kfree(wl->fw_status);
1005 kfree(wl->raw_fw_status);
1006 return -ENOMEM;
1010} 1007}
1011 1008
1012static int wl12xx_set_power_on(struct wl1271 *wl) 1009static int wl12xx_set_power_on(struct wl1271 *wl)
@@ -1767,6 +1764,12 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1767 flush_work(&wl->tx_work); 1764 flush_work(&wl->tx_work);
1768 flush_delayed_work(&wl->elp_work); 1765 flush_delayed_work(&wl->elp_work);
1769 1766
1767 /*
1768 * Cancel the watchdog even if above tx_flush failed. We will detect
1769 * it on resume anyway.
1770 */
1771 cancel_delayed_work(&wl->tx_watchdog_work);
1772
1770 return 0; 1773 return 0;
1771} 1774}
1772 1775
@@ -1824,6 +1827,13 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
1824 1827
1825out: 1828out:
1826 wl->wow_enabled = false; 1829 wl->wow_enabled = false;
1830
1831 /*
1832 * Set a flag to re-init the watchdog on the first Tx after resume.
1833 * That way we avoid possible conditions where Tx-complete interrupts
1834 * fail to arrive and we perform a spurious recovery.
1835 */
1836 set_bit(WL1271_FLAG_REINIT_TX_WDOG, &wl->flags);
1827 mutex_unlock(&wl->mutex); 1837 mutex_unlock(&wl->mutex);
1828 1838
1829 return 0; 1839 return 0;
@@ -1914,6 +1924,7 @@ static void wlcore_op_stop_locked(struct wl1271 *wl)
1914 memset(wl->links_map, 0, sizeof(wl->links_map)); 1924 memset(wl->links_map, 0, sizeof(wl->links_map));
1915 memset(wl->roc_map, 0, sizeof(wl->roc_map)); 1925 memset(wl->roc_map, 0, sizeof(wl->roc_map));
1916 memset(wl->session_ids, 0, sizeof(wl->session_ids)); 1926 memset(wl->session_ids, 0, sizeof(wl->session_ids));
1927 memset(wl->rx_filter_enabled, 0, sizeof(wl->rx_filter_enabled));
1917 wl->active_sta_count = 0; 1928 wl->active_sta_count = 0;
1918 wl->active_link_count = 0; 1929 wl->active_link_count = 0;
1919 1930
@@ -1938,9 +1949,10 @@ static void wlcore_op_stop_locked(struct wl1271 *wl)
1938 1949
1939 wl1271_debugfs_reset(wl); 1950 wl1271_debugfs_reset(wl);
1940 1951
1941 kfree(wl->fw_status_1); 1952 kfree(wl->raw_fw_status);
1942 wl->fw_status_1 = NULL; 1953 wl->raw_fw_status = NULL;
1943 wl->fw_status_2 = NULL; 1954 kfree(wl->fw_status);
1955 wl->fw_status = NULL;
1944 kfree(wl->tx_res_if); 1956 kfree(wl->tx_res_if);
1945 wl->tx_res_if = NULL; 1957 wl->tx_res_if = NULL;
1946 kfree(wl->target_mem_map); 1958 kfree(wl->target_mem_map);
@@ -2571,10 +2583,8 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2571 ieee80211_scan_completed(wl->hw, true); 2583 ieee80211_scan_completed(wl->hw, true);
2572 } 2584 }
2573 2585
2574 if (wl->sched_vif == wlvif) { 2586 if (wl->sched_vif == wlvif)
2575 ieee80211_sched_scan_stopped(wl->hw);
2576 wl->sched_vif = NULL; 2587 wl->sched_vif = NULL;
2577 }
2578 2588
2579 if (wl->roc_vif == vif) { 2589 if (wl->roc_vif == vif) {
2580 wl->roc_vif = NULL; 2590 wl->roc_vif = NULL;
@@ -2931,6 +2941,11 @@ static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2931 ret = wl1271_acx_keep_alive_mode(wl, wlvif, false); 2941 ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
2932 if (ret < 0) 2942 if (ret < 0)
2933 return ret; 2943 return ret;
2944
2945 /* disable beacon filtering */
2946 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
2947 if (ret < 0)
2948 return ret;
2934 } 2949 }
2935 2950
2936 if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) { 2951 if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) {
@@ -3463,6 +3478,10 @@ static void wl1271_op_set_default_key_idx(struct ieee80211_hw *hw,
3463 wl1271_debug(DEBUG_MAC80211, "mac80211 set default key idx %d", 3478 wl1271_debug(DEBUG_MAC80211, "mac80211 set default key idx %d",
3464 key_idx); 3479 key_idx);
3465 3480
3481 /* we don't handle unsetting of default key */
3482 if (key_idx == -1)
3483 return;
3484
3466 mutex_lock(&wl->mutex); 3485 mutex_lock(&wl->mutex);
3467 3486
3468 if (unlikely(wl->state != WLCORE_STATE_ON)) { 3487 if (unlikely(wl->state != WLCORE_STATE_ON)) {
@@ -3649,8 +3668,8 @@ out:
3649 return ret; 3668 return ret;
3650} 3669}
3651 3670
3652static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, 3671static int wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
3653 struct ieee80211_vif *vif) 3672 struct ieee80211_vif *vif)
3654{ 3673{
3655 struct wl1271 *wl = hw->priv; 3674 struct wl1271 *wl = hw->priv;
3656 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 3675 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
@@ -3672,6 +3691,8 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
3672 wl1271_ps_elp_sleep(wl); 3691 wl1271_ps_elp_sleep(wl);
3673out: 3692out:
3674 mutex_unlock(&wl->mutex); 3693 mutex_unlock(&wl->mutex);
3694
3695 return 0;
3675} 3696}
3676 3697
3677static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) 3698static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
@@ -4298,6 +4319,13 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
4298 } 4319 }
4299 } 4320 }
4300 4321
4322 if ((changed & BSS_CHANGED_BEACON_INFO) && bss_conf->dtim_period) {
4323 /* enable beacon filtering */
4324 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
4325 if (ret < 0)
4326 goto out;
4327 }
4328
4301 ret = wl1271_bss_erp_info_changed(wl, vif, bss_conf, changed); 4329 ret = wl1271_bss_erp_info_changed(wl, vif, bss_conf, changed);
4302 if (ret < 0) 4330 if (ret < 0)
4303 goto out; 4331 goto out;
@@ -4651,7 +4679,7 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
4651 int ret; 4679 int ret;
4652 4680
4653 4681
4654 if (wl->active_sta_count >= AP_MAX_STATIONS) { 4682 if (wl->active_sta_count >= wl->max_ap_stations) {
4655 wl1271_warning("could not allocate HLID - too much stations"); 4683 wl1271_warning("could not allocate HLID - too much stations");
4656 return -EBUSY; 4684 return -EBUSY;
4657 } 4685 }
@@ -4754,7 +4782,7 @@ static int wl12xx_sta_remove(struct wl1271 *wl,
4754 if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map))) 4782 if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map)))
4755 return -EINVAL; 4783 return -EINVAL;
4756 4784
4757 ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid); 4785 ret = wl12xx_cmd_remove_peer(wl, wlvif, wl_sta->hlid);
4758 if (ret < 0) 4786 if (ret < 0)
4759 return ret; 4787 return ret;
4760 4788
@@ -5679,28 +5707,6 @@ static void wl1271_unregister_hw(struct wl1271 *wl)
5679 5707
5680} 5708}
5681 5709
5682static const struct ieee80211_iface_limit wlcore_iface_limits[] = {
5683 {
5684 .max = 3,
5685 .types = BIT(NL80211_IFTYPE_STATION),
5686 },
5687 {
5688 .max = 1,
5689 .types = BIT(NL80211_IFTYPE_AP) |
5690 BIT(NL80211_IFTYPE_P2P_GO) |
5691 BIT(NL80211_IFTYPE_P2P_CLIENT),
5692 },
5693};
5694
5695static struct ieee80211_iface_combination
5696wlcore_iface_combinations[] = {
5697 {
5698 .max_interfaces = 3,
5699 .limits = wlcore_iface_limits,
5700 .n_limits = ARRAY_SIZE(wlcore_iface_limits),
5701 },
5702};
5703
5704static int wl1271_init_ieee80211(struct wl1271 *wl) 5710static int wl1271_init_ieee80211(struct wl1271 *wl)
5705{ 5711{
5706 int i; 5712 int i;
@@ -5733,7 +5739,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5733 IEEE80211_HW_AP_LINK_PS | 5739 IEEE80211_HW_AP_LINK_PS |
5734 IEEE80211_HW_AMPDU_AGGREGATION | 5740 IEEE80211_HW_AMPDU_AGGREGATION |
5735 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW | 5741 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
5736 IEEE80211_HW_QUEUE_CONTROL; 5742 IEEE80211_HW_QUEUE_CONTROL |
5743 IEEE80211_HW_CHANCTX_STA_CSA;
5737 5744
5738 wl->hw->wiphy->cipher_suites = cipher_suites; 5745 wl->hw->wiphy->cipher_suites = cipher_suites;
5739 wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 5746 wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
@@ -5821,10 +5828,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5821 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; 5828 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
5822 5829
5823 /* allowed interface combinations */ 5830 /* allowed interface combinations */
5824 wlcore_iface_combinations[0].num_different_channels = wl->num_channels; 5831 wl->hw->wiphy->iface_combinations = wl->iface_combinations;
5825 wl->hw->wiphy->iface_combinations = wlcore_iface_combinations; 5832 wl->hw->wiphy->n_iface_combinations = wl->n_iface_combinations;
5826 wl->hw->wiphy->n_iface_combinations =
5827 ARRAY_SIZE(wlcore_iface_combinations);
5828 5833
5829 SET_IEEE80211_DEV(wl->hw, wl->dev); 5834 SET_IEEE80211_DEV(wl->hw, wl->dev);
5830 5835
@@ -5844,8 +5849,6 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
5844 int i, j, ret; 5849 int i, j, ret;
5845 unsigned int order; 5850 unsigned int order;
5846 5851
5847 BUILD_BUG_ON(AP_MAX_STATIONS > WL12XX_MAX_LINKS);
5848
5849 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); 5852 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
5850 if (!hw) { 5853 if (!hw) {
5851 wl1271_error("could not alloc ieee80211_hw"); 5854 wl1271_error("could not alloc ieee80211_hw");
@@ -5867,8 +5870,12 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
5867 5870
5868 wl->hw = hw; 5871 wl->hw = hw;
5869 5872
5873 /*
5874 * wl->num_links is not configured yet, so just use WLCORE_MAX_LINKS.
5875 * we don't allocate any additional resource here, so that's fine.
5876 */
5870 for (i = 0; i < NUM_TX_QUEUES; i++) 5877 for (i = 0; i < NUM_TX_QUEUES; i++)
5871 for (j = 0; j < WL12XX_MAX_LINKS; j++) 5878 for (j = 0; j < WLCORE_MAX_LINKS; j++)
5872 skb_queue_head_init(&wl->links[j].tx_queue[i]); 5879 skb_queue_head_init(&wl->links[j].tx_queue[i]);
5873 5880
5874 skb_queue_head_init(&wl->deferred_rx_queue); 5881 skb_queue_head_init(&wl->deferred_rx_queue);
@@ -6011,7 +6018,8 @@ int wlcore_free_hw(struct wl1271 *wl)
6011 kfree(wl->nvs); 6018 kfree(wl->nvs);
6012 wl->nvs = NULL; 6019 wl->nvs = NULL;
6013 6020
6014 kfree(wl->fw_status_1); 6021 kfree(wl->raw_fw_status);
6022 kfree(wl->fw_status);
6015 kfree(wl->tx_res_if); 6023 kfree(wl->tx_res_if);
6016 destroy_workqueue(wl->freezable_wq); 6024 destroy_workqueue(wl->freezable_wq);
6017 6025
diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index 26bfc365ba70..b52516eed7b2 100644
--- a/drivers/net/wireless/ti/wlcore/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -280,7 +280,11 @@ void wl12xx_ps_link_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
280 struct ieee80211_sta *sta; 280 struct ieee80211_sta *sta;
281 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 281 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
282 282
283 if (test_bit(hlid, &wl->ap_ps_map)) 283 if (WARN_ON_ONCE(wlvif->bss_type != BSS_TYPE_AP_BSS))
284 return;
285
286 if (!test_bit(hlid, wlvif->ap.sta_hlid_map) ||
287 test_bit(hlid, &wl->ap_ps_map))
284 return; 288 return;
285 289
286 wl1271_debug(DEBUG_PSM, "start mac80211 PSM on hlid %d pkts %d " 290 wl1271_debug(DEBUG_PSM, "start mac80211 PSM on hlid %d pkts %d "
diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c
index 6791a1a6afba..e125974285cc 100644
--- a/drivers/net/wireless/ti/wlcore/rx.c
+++ b/drivers/net/wireless/ti/wlcore/rx.c
@@ -203,9 +203,9 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
203 return is_data; 203 return is_data;
204} 204}
205 205
206int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) 206int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status)
207{ 207{
208 unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; 208 unsigned long active_hlids[BITS_TO_LONGS(WLCORE_MAX_LINKS)] = {0};
209 u32 buf_size; 209 u32 buf_size;
210 u32 fw_rx_counter = status->fw_rx_counter % wl->num_rx_desc; 210 u32 fw_rx_counter = status->fw_rx_counter % wl->num_rx_desc;
211 u32 drv_rx_counter = wl->rx_counter % wl->num_rx_desc; 211 u32 drv_rx_counter = wl->rx_counter % wl->num_rx_desc;
@@ -263,12 +263,12 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status)
263 wl->aggr_buf + pkt_offset, 263 wl->aggr_buf + pkt_offset,
264 pkt_len, rx_align, 264 pkt_len, rx_align,
265 &hlid) == 1) { 265 &hlid) == 1) {
266 if (hlid < WL12XX_MAX_LINKS) 266 if (hlid < wl->num_links)
267 __set_bit(hlid, active_hlids); 267 __set_bit(hlid, active_hlids);
268 else 268 else
269 WARN(1, 269 WARN(1,
270 "hlid exceeded WL12XX_MAX_LINKS " 270 "hlid (%d) exceeded MAX_LINKS\n",
271 "(%d)\n", hlid); 271 hlid);
272 } 272 }
273 273
274 wl->rx_counter++; 274 wl->rx_counter++;
@@ -302,7 +302,7 @@ int wl1271_rx_filter_enable(struct wl1271 *wl,
302{ 302{
303 int ret; 303 int ret;
304 304
305 if (wl->rx_filter_enabled[index] == enable) { 305 if (!!test_bit(index, wl->rx_filter_enabled) == enable) {
306 wl1271_warning("Request to enable an already " 306 wl1271_warning("Request to enable an already "
307 "enabled rx filter %d", index); 307 "enabled rx filter %d", index);
308 return 0; 308 return 0;
@@ -316,7 +316,10 @@ int wl1271_rx_filter_enable(struct wl1271 *wl,
316 return ret; 316 return ret;
317 } 317 }
318 318
319 wl->rx_filter_enabled[index] = enable; 319 if (enable)
320 __set_bit(index, wl->rx_filter_enabled);
321 else
322 __clear_bit(index, wl->rx_filter_enabled);
320 323
321 return 0; 324 return 0;
322} 325}
@@ -326,7 +329,7 @@ int wl1271_rx_filter_clear_all(struct wl1271 *wl)
326 int i, ret = 0; 329 int i, ret = 0;
327 330
328 for (i = 0; i < WL1271_MAX_RX_FILTERS; i++) { 331 for (i = 0; i < WL1271_MAX_RX_FILTERS; i++) {
329 if (!wl->rx_filter_enabled[i]) 332 if (!test_bit(i, wl->rx_filter_enabled))
330 continue; 333 continue;
331 ret = wl1271_rx_filter_enable(wl, i, 0, NULL); 334 ret = wl1271_rx_filter_enable(wl, i, 0, NULL);
332 if (ret) 335 if (ret)
diff --git a/drivers/net/wireless/ti/wlcore/rx.h b/drivers/net/wireless/ti/wlcore/rx.h
index 3363f60fb7da..a3b1618db27c 100644
--- a/drivers/net/wireless/ti/wlcore/rx.h
+++ b/drivers/net/wireless/ti/wlcore/rx.h
@@ -142,7 +142,7 @@ struct wl1271_rx_descriptor {
142 u8 reserved; 142 u8 reserved;
143} __packed; 143} __packed;
144 144
145int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status); 145int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status);
146u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); 146u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
147int wl1271_rx_filter_enable(struct wl1271 *wl, 147int wl1271_rx_filter_enable(struct wl1271 *wl,
148 int index, bool enable, 148 int index, bool enable,
diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c
index b2c018dccf18..dbe826dd7c23 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -211,7 +211,7 @@ static int __must_check wl12xx_spi_raw_read(struct device *child, int addr,
211 u32 chunk_len; 211 u32 chunk_len;
212 212
213 while (len > 0) { 213 while (len > 0) {
214 chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); 214 chunk_len = min_t(size_t, WSPI_MAX_CHUNK_SIZE, len);
215 215
216 cmd = &wl->buffer_cmd; 216 cmd = &wl->buffer_cmd;
217 busy_buf = wl->buffer_busyword; 217 busy_buf = wl->buffer_busyword;
@@ -285,7 +285,7 @@ static int __must_check wl12xx_spi_raw_write(struct device *child, int addr,
285 cmd = &commands[0]; 285 cmd = &commands[0];
286 i = 0; 286 i = 0;
287 while (len > 0) { 287 while (len > 0) {
288 chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); 288 chunk_len = min_t(size_t, WSPI_MAX_CHUNK_SIZE, len);
289 289
290 *cmd = 0; 290 *cmd = 0;
291 *cmd |= WSPI_CMD_WRITE; 291 *cmd |= WSPI_CMD_WRITE;
diff --git a/drivers/net/wireless/ti/wlcore/sysfs.c b/drivers/net/wireless/ti/wlcore/sysfs.c
index 8e583497940d..24dd288d6809 100644
--- a/drivers/net/wireless/ti/wlcore/sysfs.c
+++ b/drivers/net/wireless/ti/wlcore/sysfs.c
@@ -152,7 +152,7 @@ static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj,
152 } 152 }
153 153
154 /* Seeking is not supported - old logs are not kept. Disregard pos. */ 154 /* Seeking is not supported - old logs are not kept. Disregard pos. */
155 len = min(count, (size_t)wl->fwlog_size); 155 len = min_t(size_t, count, wl->fwlog_size);
156 wl->fwlog_size -= len; 156 wl->fwlog_size -= len;
157 memcpy(buffer, wl->fwlog, len); 157 memcpy(buffer, wl->fwlog, len);
158 158
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 87cd707affa2..40b43115f835 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -101,7 +101,7 @@ static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl,
101 * authentication response. this way it won't get de-authed by FW 101 * authentication response. this way it won't get de-authed by FW
102 * when transmitting too soon. 102 * when transmitting too soon.
103 */ 103 */
104 wl1271_acx_set_inconnection_sta(wl, hdr->addr1); 104 wl1271_acx_set_inconnection_sta(wl, wlvif, hdr->addr1);
105 105
106 /* 106 /*
107 * ROC for 1 second on the AP channel for completing the connection. 107 * ROC for 1 second on the AP channel for completing the connection.
@@ -134,12 +134,12 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl,
134 * into high-level PS and clean out its TX queues. 134 * into high-level PS and clean out its TX queues.
135 * Make an exception if this is the only connected link. In this 135 * Make an exception if this is the only connected link. In this
136 * case FW-memory congestion is less of a problem. 136 * case FW-memory congestion is less of a problem.
137 * Note that a single connected STA means 3 active links, since we must 137 * Note that a single connected STA means 2*ap_count + 1 active links,
138 * account for the global and broadcast AP links. The "fw_ps" check 138 * since we must account for the global and broadcast AP links
139 * assures us the third link is a STA connected to the AP. Otherwise 139 * for each AP. The "fw_ps" check assures us the other link is a STA
140 * the FW would not set the PSM bit. 140 * connected to the AP. Otherwise the FW would not set the PSM bit.
141 */ 141 */
142 if (wl->active_link_count > 3 && fw_ps && 142 if (wl->active_link_count > (wl->ap_count*2 + 1) && fw_ps &&
143 tx_pkts >= WL1271_PS_STA_MAX_PACKETS) 143 tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
144 wl12xx_ps_link_start(wl, wlvif, hlid, true); 144 wl12xx_ps_link_start(wl, wlvif, hlid, true);
145} 145}
@@ -234,8 +234,13 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
234 wl->tx_blocks_available -= total_blocks; 234 wl->tx_blocks_available -= total_blocks;
235 wl->tx_allocated_blocks += total_blocks; 235 wl->tx_allocated_blocks += total_blocks;
236 236
237 /* If the FW was empty before, arm the Tx watchdog */ 237 /*
238 if (wl->tx_allocated_blocks == total_blocks) 238 * If the FW was empty before, arm the Tx watchdog. Also do
239 * this on the first Tx after resume, as we always cancel the
240 * watchdog on suspend.
241 */
242 if (wl->tx_allocated_blocks == total_blocks ||
243 test_and_clear_bit(WL1271_FLAG_REINIT_TX_WDOG, &wl->flags))
239 wl12xx_rearm_tx_watchdog_locked(wl); 244 wl12xx_rearm_tx_watchdog_locked(wl);
240 245
241 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); 246 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
@@ -357,6 +362,10 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
357 ieee80211_has_protected(frame_control)) 362 ieee80211_has_protected(frame_control))
358 tx_attr |= TX_HW_ATTR_HOST_ENCRYPT; 363 tx_attr |= TX_HW_ATTR_HOST_ENCRYPT;
359 364
365 /* send EAPOL frames as voice */
366 if (control->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)
367 tx_attr |= TX_HW_ATTR_EAPOL_FRAME;
368
360 desc->tx_attr = cpu_to_le16(tx_attr); 369 desc->tx_attr = cpu_to_le16(tx_attr);
361 370
362 wlcore_hw_set_tx_desc_csum(wl, desc, skb); 371 wlcore_hw_set_tx_desc_csum(wl, desc, skb);
@@ -560,11 +569,11 @@ static struct sk_buff *wlcore_vif_dequeue_high_prio(struct wl1271 *wl,
560 int i, h, start_hlid; 569 int i, h, start_hlid;
561 570
562 /* start from the link after the last one */ 571 /* start from the link after the last one */
563 start_hlid = (wlvif->last_tx_hlid + 1) % WL12XX_MAX_LINKS; 572 start_hlid = (wlvif->last_tx_hlid + 1) % wl->num_links;
564 573
565 /* dequeue according to AC, round robin on each link */ 574 /* dequeue according to AC, round robin on each link */
566 for (i = 0; i < WL12XX_MAX_LINKS; i++) { 575 for (i = 0; i < wl->num_links; i++) {
567 h = (start_hlid + i) % WL12XX_MAX_LINKS; 576 h = (start_hlid + i) % wl->num_links;
568 577
569 /* only consider connected stations */ 578 /* only consider connected stations */
570 if (!test_bit(h, wlvif->links_map)) 579 if (!test_bit(h, wlvif->links_map))
@@ -688,8 +697,8 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct wl12xx_vif *wlvif,
688 skb_queue_head(&wl->links[hlid].tx_queue[q], skb); 697 skb_queue_head(&wl->links[hlid].tx_queue[q], skb);
689 698
690 /* make sure we dequeue the same packet next time */ 699 /* make sure we dequeue the same packet next time */
691 wlvif->last_tx_hlid = (hlid + WL12XX_MAX_LINKS - 1) % 700 wlvif->last_tx_hlid = (hlid + wl->num_links - 1) %
692 WL12XX_MAX_LINKS; 701 wl->num_links;
693 } 702 }
694 703
695 spin_lock_irqsave(&wl->wl_lock, flags); 704 spin_lock_irqsave(&wl->wl_lock, flags);
@@ -722,7 +731,7 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids)
722 timeout = wl->conf.rx_streaming.duration; 731 timeout = wl->conf.rx_streaming.duration;
723 wl12xx_for_each_wlvif_sta(wl, wlvif) { 732 wl12xx_for_each_wlvif_sta(wl, wlvif) {
724 bool found = false; 733 bool found = false;
725 for_each_set_bit(hlid, active_hlids, WL12XX_MAX_LINKS) { 734 for_each_set_bit(hlid, active_hlids, wl->num_links) {
726 if (test_bit(hlid, wlvif->links_map)) { 735 if (test_bit(hlid, wlvif->links_map)) {
727 found = true; 736 found = true;
728 break; 737 break;
@@ -759,7 +768,7 @@ int wlcore_tx_work_locked(struct wl1271 *wl)
759 struct wl1271_tx_hw_descr *desc; 768 struct wl1271_tx_hw_descr *desc;
760 u32 buf_offset = 0, last_len = 0; 769 u32 buf_offset = 0, last_len = 0;
761 bool sent_packets = false; 770 bool sent_packets = false;
762 unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; 771 unsigned long active_hlids[BITS_TO_LONGS(WLCORE_MAX_LINKS)] = {0};
763 int ret = 0; 772 int ret = 0;
764 int bus_ret = 0; 773 int bus_ret = 0;
765 u8 hlid; 774 u8 hlid;
@@ -1061,7 +1070,7 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1061 int i; 1070 int i;
1062 1071
1063 /* TX failure */ 1072 /* TX failure */
1064 for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) { 1073 for_each_set_bit(i, wlvif->links_map, wl->num_links) {
1065 if (wlvif->bss_type == BSS_TYPE_AP_BSS && 1074 if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
1066 i != wlvif->ap.bcast_hlid && i != wlvif->ap.global_hlid) { 1075 i != wlvif->ap.bcast_hlid && i != wlvif->ap.global_hlid) {
1067 /* this calls wl12xx_free_link */ 1076 /* this calls wl12xx_free_link */
@@ -1085,7 +1094,7 @@ void wl12xx_tx_reset(struct wl1271 *wl)
1085 1094
1086 /* only reset the queues if something bad happened */ 1095 /* only reset the queues if something bad happened */
1087 if (wl1271_tx_total_queue_count(wl) != 0) { 1096 if (wl1271_tx_total_queue_count(wl) != 0) {
1088 for (i = 0; i < WL12XX_MAX_LINKS; i++) 1097 for (i = 0; i < wl->num_links; i++)
1089 wl1271_tx_reset_link_queues(wl, i); 1098 wl1271_tx_reset_link_queues(wl, i);
1090 1099
1091 for (i = 0; i < NUM_TX_QUEUES; i++) 1100 for (i = 0; i < NUM_TX_QUEUES; i++)
@@ -1178,7 +1187,7 @@ void wl1271_tx_flush(struct wl1271 *wl)
1178 WL1271_TX_FLUSH_TIMEOUT / 1000); 1187 WL1271_TX_FLUSH_TIMEOUT / 1000);
1179 1188
1180 /* forcibly flush all Tx buffers on our queues */ 1189 /* forcibly flush all Tx buffers on our queues */
1181 for (i = 0; i < WL12XX_MAX_LINKS; i++) 1190 for (i = 0; i < wl->num_links; i++)
1182 wl1271_tx_reset_link_queues(wl, i); 1191 wl1271_tx_reset_link_queues(wl, i);
1183 1192
1184out_wake: 1193out_wake:
diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h
index 35489c300da1..79cb3ff8b71f 100644
--- a/drivers/net/wireless/ti/wlcore/tx.h
+++ b/drivers/net/wireless/ti/wlcore/tx.h
@@ -37,6 +37,7 @@
37#define TX_HW_ATTR_TX_CMPLT_REQ BIT(12) 37#define TX_HW_ATTR_TX_CMPLT_REQ BIT(12)
38#define TX_HW_ATTR_TX_DUMMY_REQ BIT(13) 38#define TX_HW_ATTR_TX_DUMMY_REQ BIT(13)
39#define TX_HW_ATTR_HOST_ENCRYPT BIT(14) 39#define TX_HW_ATTR_HOST_ENCRYPT BIT(14)
40#define TX_HW_ATTR_EAPOL_FRAME BIT(15)
40 41
41#define TX_HW_ATTR_OFST_SAVE_RETRIES 0 42#define TX_HW_ATTR_OFST_SAVE_RETRIES 0
42#define TX_HW_ATTR_OFST_HEADER_PAD 1 43#define TX_HW_ATTR_OFST_HEADER_PAD 1
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 06efc12a39e5..95a54504f0cc 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -73,6 +73,8 @@ struct wlcore_ops {
73 void (*tx_immediate_compl)(struct wl1271 *wl); 73 void (*tx_immediate_compl)(struct wl1271 *wl);
74 int (*hw_init)(struct wl1271 *wl); 74 int (*hw_init)(struct wl1271 *wl);
75 int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif); 75 int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
76 void (*convert_fw_status)(struct wl1271 *wl, void *raw_fw_status,
77 struct wl_fw_status *fw_status);
76 u32 (*sta_get_ap_rate_mask)(struct wl1271 *wl, 78 u32 (*sta_get_ap_rate_mask)(struct wl1271 *wl,
77 struct wl12xx_vif *wlvif); 79 struct wl12xx_vif *wlvif);
78 int (*get_pg_ver)(struct wl1271 *wl, s8 *ver); 80 int (*get_pg_ver)(struct wl1271 *wl, s8 *ver);
@@ -220,7 +222,7 @@ struct wl1271 {
220 int channel; 222 int channel;
221 u8 system_hlid; 223 u8 system_hlid;
222 224
223 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; 225 unsigned long links_map[BITS_TO_LONGS(WLCORE_MAX_LINKS)];
224 unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; 226 unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
225 unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; 227 unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
226 unsigned long rate_policies_map[ 228 unsigned long rate_policies_map[
@@ -228,7 +230,7 @@ struct wl1271 {
228 unsigned long klv_templates_map[ 230 unsigned long klv_templates_map[
229 BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)]; 231 BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)];
230 232
231 u8 session_ids[WL12XX_MAX_LINKS]; 233 u8 session_ids[WLCORE_MAX_LINKS];
232 234
233 struct list_head wlvif_list; 235 struct list_head wlvif_list;
234 236
@@ -346,8 +348,8 @@ struct wl1271 {
346 u32 buffer_cmd; 348 u32 buffer_cmd;
347 u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; 349 u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
348 350
349 struct wl_fw_status_1 *fw_status_1; 351 void *raw_fw_status;
350 struct wl_fw_status_2 *fw_status_2; 352 struct wl_fw_status *fw_status;
351 struct wl1271_tx_hw_res_if *tx_res_if; 353 struct wl1271_tx_hw_res_if *tx_res_if;
352 354
353 /* Current chipset configuration */ 355 /* Current chipset configuration */
@@ -376,7 +378,7 @@ struct wl1271 {
376 * AP-mode - links indexed by HLID. The global and broadcast links 378 * AP-mode - links indexed by HLID. The global and broadcast links
377 * are always active. 379 * are always active.
378 */ 380 */
379 struct wl1271_link links[WL12XX_MAX_LINKS]; 381 struct wl1271_link links[WLCORE_MAX_LINKS];
380 382
381 /* number of currently active links */ 383 /* number of currently active links */
382 int active_link_count; 384 int active_link_count;
@@ -405,6 +407,9 @@ struct wl1271 {
405 /* AP-mode - number of currently connected stations */ 407 /* AP-mode - number of currently connected stations */
406 int active_sta_count; 408 int active_sta_count;
407 409
410 /* Flag determining whether AP should broadcast OFDM-only rates */
411 bool ofdm_only_ap;
412
408 /* last wlvif we transmitted from */ 413 /* last wlvif we transmitted from */
409 struct wl12xx_vif *last_wlvif; 414 struct wl12xx_vif *last_wlvif;
410 415
@@ -434,6 +439,10 @@ struct wl1271 {
434 u32 num_tx_desc; 439 u32 num_tx_desc;
435 /* number of RX descriptors the HW supports. */ 440 /* number of RX descriptors the HW supports. */
436 u32 num_rx_desc; 441 u32 num_rx_desc;
442 /* number of links the HW supports */
443 u8 num_links;
444 /* max stations a single AP can support */
445 u8 max_ap_stations;
437 446
438 /* translate HW Tx rates to standard rate-indices */ 447 /* translate HW Tx rates to standard rate-indices */
439 const u8 **band_rate_to_idx; 448 const u8 **band_rate_to_idx;
@@ -448,10 +457,11 @@ struct wl1271 {
448 struct ieee80211_sta_ht_cap ht_cap[WLCORE_NUM_BANDS]; 457 struct ieee80211_sta_ht_cap ht_cap[WLCORE_NUM_BANDS];
449 458
450 /* size of the private FW status data */ 459 /* size of the private FW status data */
460 size_t fw_status_len;
451 size_t fw_status_priv_len; 461 size_t fw_status_priv_len;
452 462
453 /* RX Data filter rule state - enabled/disabled */ 463 /* RX Data filter rule state - enabled/disabled */
454 bool rx_filter_enabled[WL1271_MAX_RX_FILTERS]; 464 unsigned long rx_filter_enabled[BITS_TO_LONGS(WL1271_MAX_RX_FILTERS)];
455 465
456 /* size of the private static data */ 466 /* size of the private static data */
457 size_t static_data_priv_len; 467 size_t static_data_priv_len;
@@ -476,8 +486,9 @@ struct wl1271 {
476 486
477 struct completion nvs_loading_complete; 487 struct completion nvs_loading_complete;
478 488
479 /* number of concurrent channels the HW supports */ 489 /* interface combinations supported by the hw */
480 u32 num_channels; 490 const struct ieee80211_iface_combination *iface_combinations;
491 u8 n_iface_combinations;
481}; 492};
482 493
483int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); 494int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index ce7261ce8b59..756e890bc5ee 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -58,10 +58,15 @@
58#define WL1271_DEFAULT_DTIM_PERIOD 1 58#define WL1271_DEFAULT_DTIM_PERIOD 1
59 59
60#define WL12XX_MAX_ROLES 4 60#define WL12XX_MAX_ROLES 4
61#define WL12XX_MAX_LINKS 12
62#define WL12XX_INVALID_ROLE_ID 0xff 61#define WL12XX_INVALID_ROLE_ID 0xff
63#define WL12XX_INVALID_LINK_ID 0xff 62#define WL12XX_INVALID_LINK_ID 0xff
64 63
64/*
65 * max number of links allowed by all HWs.
66 * this is NOT the actual max links supported by the current hw.
67 */
68#define WLCORE_MAX_LINKS 16
69
65/* the driver supports the 2.4Ghz and 5Ghz bands */ 70/* the driver supports the 2.4Ghz and 5Ghz bands */
66#define WLCORE_NUM_BANDS 2 71#define WLCORE_NUM_BANDS 2
67 72
@@ -118,72 +123,58 @@ struct wl1271_chip {
118 123
119#define NUM_TX_QUEUES 4 124#define NUM_TX_QUEUES 4
120 125
121#define AP_MAX_STATIONS 8 126struct wl_fw_status {
122 127 u32 intr;
123struct wl_fw_packet_counters {
124 /* Cumulative counter of released packets per AC */
125 u8 tx_released_pkts[NUM_TX_QUEUES];
126
127 /* Cumulative counter of freed packets per HLID */
128 u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
129
130 /* Cumulative counter of released Voice memory blocks */
131 u8 tx_voice_released_blks;
132
133 /* Tx rate of the last transmitted packet */
134 u8 tx_last_rate;
135
136 u8 padding[2];
137} __packed;
138
139/* FW status registers */
140struct wl_fw_status_1 {
141 __le32 intr;
142 u8 fw_rx_counter; 128 u8 fw_rx_counter;
143 u8 drv_rx_counter; 129 u8 drv_rx_counter;
144 u8 reserved;
145 u8 tx_results_counter; 130 u8 tx_results_counter;
146 __le32 rx_pkt_descs[0]; 131 __le32 *rx_pkt_descs;
147} __packed;
148
149/*
150 * Each HW arch has a different number of Rx descriptors.
151 * The length of the status depends on it, since it holds an array
152 * of descriptors.
153 */
154#define WLCORE_FW_STATUS_1_LEN(num_rx_desc) \
155 (sizeof(struct wl_fw_status_1) + \
156 (sizeof(((struct wl_fw_status_1 *)0)->rx_pkt_descs[0])) * \
157 num_rx_desc)
158 132
159struct wl_fw_status_2 { 133 u32 fw_localtime;
160 __le32 fw_localtime;
161 134
162 /* 135 /*
163 * A bitmap (where each bit represents a single HLID) 136 * A bitmap (where each bit represents a single HLID)
164 * to indicate if the station is in PS mode. 137 * to indicate if the station is in PS mode.
165 */ 138 */
166 __le32 link_ps_bitmap; 139 u32 link_ps_bitmap;
167 140
168 /* 141 /*
169 * A bitmap (where each bit represents a single HLID) to indicate 142 * A bitmap (where each bit represents a single HLID) to indicate
170 * if the station is in Fast mode 143 * if the station is in Fast mode
171 */ 144 */
172 __le32 link_fast_bitmap; 145 u32 link_fast_bitmap;
173 146
174 /* Cumulative counter of total released mem blocks since FW-reset */ 147 /* Cumulative counter of total released mem blocks since FW-reset */
175 __le32 total_released_blks; 148 u32 total_released_blks;
176 149
177 /* Size (in Memory Blocks) of TX pool */ 150 /* Size (in Memory Blocks) of TX pool */
178 __le32 tx_total; 151 u32 tx_total;
152
153 struct {
154 /*
155 * Cumulative counter of released packets per AC
156 * (length of the array is NUM_TX_QUEUES)
157 */
158 u8 *tx_released_pkts;
179 159
180 struct wl_fw_packet_counters counters; 160 /*
161 * Cumulative counter of freed packets per HLID
162 * (length of the array is wl->num_links)
163 */
164 u8 *tx_lnk_free_pkts;
165
166 /* Cumulative counter of released Voice memory blocks */
167 u8 tx_voice_released_blks;
181 168
182 __le32 log_start_addr; 169 /* Tx rate of the last transmitted packet */
170 u8 tx_last_rate;
171 } counters;
172
173 u32 log_start_addr;
183 174
184 /* Private status to be used by the lower drivers */ 175 /* Private status to be used by the lower drivers */
185 u8 priv[0]; 176 void *priv;
186} __packed; 177};
187 178
188#define WL1271_MAX_CHANNELS 64 179#define WL1271_MAX_CHANNELS 64
189struct wl1271_scan { 180struct wl1271_scan {
@@ -240,6 +231,7 @@ enum wl12xx_flags {
240 WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, 231 WL1271_FLAG_VIF_CHANGE_IN_PROGRESS,
241 WL1271_FLAG_INTENDED_FW_RECOVERY, 232 WL1271_FLAG_INTENDED_FW_RECOVERY,
242 WL1271_FLAG_IO_FAILED, 233 WL1271_FLAG_IO_FAILED,
234 WL1271_FLAG_REINIT_TX_WDOG,
243}; 235};
244 236
245enum wl12xx_vif_flags { 237enum wl12xx_vif_flags {
@@ -368,7 +360,7 @@ struct wl12xx_vif {
368 360
369 /* HLIDs bitmap of associated stations */ 361 /* HLIDs bitmap of associated stations */
370 unsigned long sta_hlid_map[BITS_TO_LONGS( 362 unsigned long sta_hlid_map[BITS_TO_LONGS(
371 WL12XX_MAX_LINKS)]; 363 WLCORE_MAX_LINKS)];
372 364
373 /* recoreded keys - set here before AP startup */ 365 /* recoreded keys - set here before AP startup */
374 struct wl1271_ap_key *recorded_keys[MAX_NUM_KEYS]; 366 struct wl1271_ap_key *recorded_keys[MAX_NUM_KEYS];
@@ -385,7 +377,7 @@ struct wl12xx_vif {
385 /* counters of packets per AC, across all links in the vif */ 377 /* counters of packets per AC, across all links in the vif */
386 int tx_queue_count[NUM_TX_QUEUES]; 378 int tx_queue_count[NUM_TX_QUEUES];
387 379
388 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; 380 unsigned long links_map[BITS_TO_LONGS(WLCORE_MAX_LINKS)];
389 381
390 u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; 382 u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
391 u8 ssid_len; 383 u8 ssid_len;