aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ti/wl18xx/main.c
diff options
context:
space:
mode:
authorLuciano Coelho <coelho@ti.com>2013-01-18 02:40:07 -0500
committerLuciano Coelho <coelho@ti.com>2013-01-18 02:59:08 -0500
commit5b37649bbcfc14c1ecfb76c5b018dd686924b946 (patch)
tree5d88b1619176b860041fdd20b64ce917b8613698 /drivers/net/wireless/ti/wl18xx/main.c
parent660b9caaad380758c756a7e60397e33dab44fe3f (diff)
parent2e07d02828759a506b5205b2cff40daa58df5bf7 (diff)
Merge branch 'wl12xx-next' into for-linville
Conflicts: drivers/net/wireless/ti/wl12xx/main.c drivers/net/wireless/ti/wlcore/wlcore.h
Diffstat (limited to 'drivers/net/wireless/ti/wl18xx/main.c')
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c267
1 files changed, 219 insertions, 48 deletions
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 8d8c1f8c63b7..0be1cfc17a86 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -34,10 +34,13 @@
34 34
35#include "reg.h" 35#include "reg.h"
36#include "conf.h" 36#include "conf.h"
37#include "cmd.h"
37#include "acx.h" 38#include "acx.h"
38#include "tx.h" 39#include "tx.h"
39#include "wl18xx.h" 40#include "wl18xx.h"
40#include "io.h" 41#include "io.h"
42#include "scan.h"
43#include "event.h"
41#include "debugfs.h" 44#include "debugfs.h"
42 45
43#define WL18XX_RX_CHECKSUM_MASK 0x40 46#define WL18XX_RX_CHECKSUM_MASK 0x40
@@ -334,6 +337,8 @@ static struct wlcore_conf wl18xx_conf = {
334 .tmpl_short_retry_limit = 10, 337 .tmpl_short_retry_limit = 10,
335 .tmpl_long_retry_limit = 10, 338 .tmpl_long_retry_limit = 10,
336 .tx_watchdog_timeout = 5000, 339 .tx_watchdog_timeout = 5000,
340 .slow_link_thold = 3,
341 .fast_link_thold = 30,
337 }, 342 },
338 .conn = { 343 .conn = {
339 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, 344 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
@@ -391,8 +396,10 @@ static struct wlcore_conf wl18xx_conf = {
391 .scan = { 396 .scan = {
392 .min_dwell_time_active = 7500, 397 .min_dwell_time_active = 7500,
393 .max_dwell_time_active = 30000, 398 .max_dwell_time_active = 30000,
394 .min_dwell_time_passive = 100000, 399 .min_dwell_time_active_long = 25000,
395 .max_dwell_time_passive = 100000, 400 .max_dwell_time_active_long = 50000,
401 .dwell_time_passive = 100000,
402 .dwell_time_dfs = 150000,
396 .num_probe_reqs = 2, 403 .num_probe_reqs = 2,
397 .split_scan_timeout = 50000, 404 .split_scan_timeout = 50000,
398 }, 405 },
@@ -489,6 +496,10 @@ static struct wlcore_conf wl18xx_conf = {
489 .increase_time = 1, 496 .increase_time = 1,
490 .window_size = 16, 497 .window_size = 16,
491 }, 498 },
499 .recovery = {
500 .bug_on_recovery = 0,
501 .no_recovery = 0,
502 },
492}; 503};
493 504
494static struct wl18xx_priv_conf wl18xx_default_priv_conf = { 505static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
@@ -501,7 +512,6 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
501 .clock_valid_on_wake_up = 0x00, 512 .clock_valid_on_wake_up = 0x00,
502 .secondary_clock_setting_time = 0x05, 513 .secondary_clock_setting_time = 0x05,
503 .board_type = BOARD_TYPE_HDK_18XX, 514 .board_type = BOARD_TYPE_HDK_18XX,
504 .rdl = 0x01,
505 .auto_detect = 0x00, 515 .auto_detect = 0x00,
506 .dedicated_fem = FEM_NONE, 516 .dedicated_fem = FEM_NONE,
507 .low_band_component = COMPONENT_3_WAY_SWITCH, 517 .low_band_component = COMPONENT_3_WAY_SWITCH,
@@ -517,14 +527,39 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
517 .enable_clpc = 0x00, 527 .enable_clpc = 0x00,
518 .enable_tx_low_pwr_on_siso_rdl = 0x00, 528 .enable_tx_low_pwr_on_siso_rdl = 0x00,
519 .rx_profile = 0x00, 529 .rx_profile = 0x00,
520 .pwr_limit_reference_11_abg = 0xc8, 530 .pwr_limit_reference_11_abg = 0x64,
531 .per_chan_pwr_limit_arr_11abg = {
532 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
533 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
534 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
535 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
536 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
537 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
538 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
539 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
540 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
541 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
542 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
543 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
544 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
545 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
546 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
547 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
548 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
549 .pwr_limit_reference_11p = 0x64,
550 .per_chan_pwr_limit_arr_11p = { 0xff, 0xff, 0xff, 0xff,
551 0xff, 0xff, 0xff },
521 .psat = 0, 552 .psat = 0,
522 .low_power_val = 0x00, 553 .low_power_val = 0x08,
523 .med_power_val = 0x0a, 554 .med_power_val = 0x12,
524 .high_power_val = 0x1e, 555 .high_power_val = 0x18,
556 .low_power_val_2nd = 0x05,
557 .med_power_val_2nd = 0x0a,
558 .high_power_val_2nd = 0x14,
525 .external_pa_dc2dc = 0, 559 .external_pa_dc2dc = 0,
526 .number_of_assembled_ant2_4 = 1, 560 .number_of_assembled_ant2_4 = 2,
527 .number_of_assembled_ant5 = 1, 561 .number_of_assembled_ant5 = 1,
562 .tx_rf_margin = 1,
528 }, 563 },
529}; 564};
530 565
@@ -595,7 +630,7 @@ static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = {
595}; 630};
596 631
597/* TODO: maybe move to a new header file? */ 632/* TODO: maybe move to a new header file? */
598#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw.bin" 633#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-2.bin"
599 634
600static int wl18xx_identify_chip(struct wl1271 *wl) 635static int wl18xx_identify_chip(struct wl1271 *wl)
601{ 636{
@@ -608,15 +643,18 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
608 wl->sr_fw_name = WL18XX_FW_NAME; 643 wl->sr_fw_name = WL18XX_FW_NAME;
609 /* wl18xx uses the same firmware for PLT */ 644 /* wl18xx uses the same firmware for PLT */
610 wl->plt_fw_name = WL18XX_FW_NAME; 645 wl->plt_fw_name = WL18XX_FW_NAME;
611 wl->quirks |= WLCORE_QUIRK_NO_ELP | 646 wl->quirks |= WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
612 WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
613 WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | 647 WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
614 WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN | 648 WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN |
615 WLCORE_QUIRK_TX_PAD_LAST_FRAME; 649 WLCORE_QUIRK_TX_PAD_LAST_FRAME |
616 650 WLCORE_QUIRK_REGDOMAIN_CONF |
617 wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER, WL18XX_IFTYPE_VER, 651 WLCORE_QUIRK_DUAL_PROBE_TMPL;
618 WL18XX_MAJOR_VER, WL18XX_SUBTYPE_VER, 652
619 WL18XX_MINOR_VER); 653 wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER,
654 WL18XX_IFTYPE_VER, WL18XX_MAJOR_VER,
655 WL18XX_SUBTYPE_VER, WL18XX_MINOR_VER,
656 /* there's no separate multi-role FW */
657 0, 0, 0, 0);
620 break; 658 break;
621 case CHIP_ID_185x_PG10: 659 case CHIP_ID_185x_PG10:
622 wl1271_warning("chip id 0x%x (185x PG10) is deprecated", 660 wl1271_warning("chip id 0x%x (185x PG10) is deprecated",
@@ -630,6 +668,11 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
630 goto out; 668 goto out;
631 } 669 }
632 670
671 wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
672 wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
673 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
674 wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC;
675 wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ;
633out: 676out:
634 return ret; 677 return ret;
635} 678}
@@ -843,6 +886,20 @@ static int wl18xx_boot(struct wl1271 *wl)
843 if (ret < 0) 886 if (ret < 0)
844 goto out; 887 goto out;
845 888
889 wl->event_mask = BSS_LOSS_EVENT_ID |
890 SCAN_COMPLETE_EVENT_ID |
891 RSSI_SNR_TRIGGER_0_EVENT_ID |
892 PERIODIC_SCAN_COMPLETE_EVENT_ID |
893 PERIODIC_SCAN_REPORT_EVENT_ID |
894 DUMMY_PACKET_EVENT_ID |
895 PEER_REMOVE_COMPLETE_EVENT_ID |
896 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
897 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
898 INACTIVE_STA_EVENT_ID |
899 MAX_TX_FAILURE_EVENT_ID |
900 CHANNEL_SWITCH_COMPLETE_EVENT_ID |
901 DFS_CHANNELS_CONFIG_COMPLETE_EVENT;
902
846 ret = wlcore_boot_run_firmware(wl); 903 ret = wlcore_boot_run_firmware(wl);
847 if (ret < 0) 904 if (ret < 0)
848 goto out; 905 goto out;
@@ -964,7 +1021,7 @@ static int wl18xx_hw_init(struct wl1271 *wl)
964 1021
965 /* (re)init private structures. Relevant on recovery as well. */ 1022 /* (re)init private structures. Relevant on recovery as well. */
966 priv->last_fw_rls_idx = 0; 1023 priv->last_fw_rls_idx = 0;
967 priv->extra_spare_vif_count = 0; 1024 priv->extra_spare_key_count = 0;
968 1025
969 /* set the default amount of spare blocks in the bitmap */ 1026 /* set the default amount of spare blocks in the bitmap */
970 ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE); 1027 ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE);
@@ -1022,7 +1079,12 @@ static bool wl18xx_is_mimo_supported(struct wl1271 *wl)
1022{ 1079{
1023 struct wl18xx_priv *priv = wl->priv; 1080 struct wl18xx_priv *priv = wl->priv;
1024 1081
1025 return priv->conf.phy.number_of_assembled_ant2_4 >= 2; 1082 /* only support MIMO with multiple antennas, and when SISO
1083 * is not forced through config
1084 */
1085 return (priv->conf.phy.number_of_assembled_ant2_4 >= 2) &&
1086 (priv->conf.ht.mode != HT_MODE_WIDE) &&
1087 (priv->conf.ht.mode != HT_MODE_SISO20);
1026} 1088}
1027 1089
1028/* 1090/*
@@ -1223,8 +1285,8 @@ static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1223{ 1285{
1224 struct wl18xx_priv *priv = wl->priv; 1286 struct wl18xx_priv *priv = wl->priv;
1225 1287
1226 /* If we have VIFs requiring extra spare, indulge them */ 1288 /* If we have keys requiring extra spare, indulge them */
1227 if (priv->extra_spare_vif_count) 1289 if (priv->extra_spare_key_count)
1228 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE; 1290 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE;
1229 1291
1230 return WL18XX_TX_HW_BLOCK_SPARE; 1292 return WL18XX_TX_HW_BLOCK_SPARE;
@@ -1236,42 +1298,48 @@ static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1236 struct ieee80211_key_conf *key_conf) 1298 struct ieee80211_key_conf *key_conf)
1237{ 1299{
1238 struct wl18xx_priv *priv = wl->priv; 1300 struct wl18xx_priv *priv = wl->priv;
1239 bool change_spare = false; 1301 bool change_spare = false, special_enc;
1240 int ret; 1302 int ret;
1241 1303
1304 wl1271_debug(DEBUG_CRYPT, "extra spare keys before: %d",
1305 priv->extra_spare_key_count);
1306
1307 special_enc = key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
1308 key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;
1309
1310 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf);
1311 if (ret < 0)
1312 goto out;
1313
1242 /* 1314 /*
1243 * when adding the first or removing the last GEM/TKIP interface, 1315 * when adding the first or removing the last GEM/TKIP key,
1244 * we have to adjust the number of spare blocks. 1316 * we have to adjust the number of spare blocks.
1245 */ 1317 */
1246 change_spare = (key_conf->cipher == WL1271_CIPHER_SUITE_GEM || 1318 if (special_enc) {
1247 key_conf->cipher == WLAN_CIPHER_SUITE_TKIP) && 1319 if (cmd == SET_KEY) {
1248 ((priv->extra_spare_vif_count == 0 && cmd == SET_KEY) || 1320 /* first key */
1249 (priv->extra_spare_vif_count == 1 && cmd == DISABLE_KEY)); 1321 change_spare = (priv->extra_spare_key_count == 0);
1322 priv->extra_spare_key_count++;
1323 } else if (cmd == DISABLE_KEY) {
1324 /* last key */
1325 change_spare = (priv->extra_spare_key_count == 1);
1326 priv->extra_spare_key_count--;
1327 }
1328 }
1250 1329
1251 /* no need to change spare - just regular set_key */ 1330 wl1271_debug(DEBUG_CRYPT, "extra spare keys after: %d",
1252 if (!change_spare) 1331 priv->extra_spare_key_count);
1253 return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1254 1332
1255 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf); 1333 if (!change_spare)
1256 if (ret < 0)
1257 goto out; 1334 goto out;
1258 1335
1259 /* key is now set, change the spare blocks */ 1336 /* key is now set, change the spare blocks */
1260 if (cmd == SET_KEY) { 1337 if (priv->extra_spare_key_count)
1261 ret = wl18xx_set_host_cfg_bitmap(wl, 1338 ret = wl18xx_set_host_cfg_bitmap(wl,
1262 WL18XX_TX_HW_EXTRA_BLOCK_SPARE); 1339 WL18XX_TX_HW_EXTRA_BLOCK_SPARE);
1263 if (ret < 0) 1340 else
1264 goto out;
1265
1266 priv->extra_spare_vif_count++;
1267 } else {
1268 ret = wl18xx_set_host_cfg_bitmap(wl, 1341 ret = wl18xx_set_host_cfg_bitmap(wl,
1269 WL18XX_TX_HW_BLOCK_SPARE); 1342 WL18XX_TX_HW_BLOCK_SPARE);
1270 if (ret < 0)
1271 goto out;
1272
1273 priv->extra_spare_vif_count--;
1274 }
1275 1343
1276out: 1344out:
1277 return ret; 1345 return ret;
@@ -1296,6 +1364,92 @@ static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1296 return buf_offset; 1364 return buf_offset;
1297} 1365}
1298 1366
1367static void wl18xx_sta_rc_update(struct wl1271 *wl,
1368 struct wl12xx_vif *wlvif,
1369 struct ieee80211_sta *sta,
1370 u32 changed)
1371{
1372 bool wide = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1373
1374 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide);
1375
1376 if (!(changed & IEEE80211_RC_BW_CHANGED))
1377 return;
1378
1379 mutex_lock(&wl->mutex);
1380
1381 /* sanity */
1382 if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
1383 goto out;
1384
1385 /* ignore the change before association */
1386 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1387 goto out;
1388
1389 /*
1390 * If we started out as wide, we can change the operation mode. If we
1391 * thought this was a 20mhz AP, we have to reconnect
1392 */
1393 if (wlvif->sta.role_chan_type == NL80211_CHAN_HT40MINUS ||
1394 wlvif->sta.role_chan_type == NL80211_CHAN_HT40PLUS)
1395 wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide);
1396 else
1397 ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif));
1398
1399out:
1400 mutex_unlock(&wl->mutex);
1401}
1402
1403static int wl18xx_set_peer_cap(struct wl1271 *wl,
1404 struct ieee80211_sta_ht_cap *ht_cap,
1405 bool allow_ht_operation,
1406 u32 rate_set, u8 hlid)
1407{
1408 return wl18xx_acx_set_peer_cap(wl, ht_cap, allow_ht_operation,
1409 rate_set, hlid);
1410}
1411
1412static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1413 struct wl1271_link *lnk)
1414{
1415 u8 thold;
1416 struct wl18xx_fw_status_priv *status_priv =
1417 (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
1418 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1419
1420 /* suspended links are never high priority */
1421 if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
1422 return false;
1423
1424 /* the priority thresholds are taken from FW */
1425 if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
1426 !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
1427 thold = status_priv->tx_fast_link_prio_threshold;
1428 else
1429 thold = status_priv->tx_slow_link_prio_threshold;
1430
1431 return lnk->allocated_pkts < thold;
1432}
1433
1434static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1435 struct wl1271_link *lnk)
1436{
1437 u8 thold;
1438 struct wl18xx_fw_status_priv *status_priv =
1439 (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
1440 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1441
1442 if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
1443 thold = status_priv->tx_suspend_threshold;
1444 else if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
1445 !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
1446 thold = status_priv->tx_fast_stop_threshold;
1447 else
1448 thold = status_priv->tx_slow_stop_threshold;
1449
1450 return lnk->allocated_pkts < thold;
1451}
1452
1299static int wl18xx_setup(struct wl1271 *wl); 1453static int wl18xx_setup(struct wl1271 *wl);
1300 1454
1301static struct wlcore_ops wl18xx_ops = { 1455static struct wlcore_ops wl18xx_ops = {
@@ -1305,6 +1459,8 @@ static struct wlcore_ops wl18xx_ops = {
1305 .plt_init = wl18xx_plt_init, 1459 .plt_init = wl18xx_plt_init,
1306 .trigger_cmd = wl18xx_trigger_cmd, 1460 .trigger_cmd = wl18xx_trigger_cmd,
1307 .ack_event = wl18xx_ack_event, 1461 .ack_event = wl18xx_ack_event,
1462 .wait_for_event = wl18xx_wait_for_event,
1463 .process_mailbox_events = wl18xx_process_mailbox_events,
1308 .calc_tx_blocks = wl18xx_calc_tx_blocks, 1464 .calc_tx_blocks = wl18xx_calc_tx_blocks,
1309 .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks, 1465 .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks,
1310 .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len, 1466 .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len,
@@ -1320,16 +1476,26 @@ static struct wlcore_ops wl18xx_ops = {
1320 .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, 1476 .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask,
1321 .get_mac = wl18xx_get_mac, 1477 .get_mac = wl18xx_get_mac,
1322 .debugfs_init = wl18xx_debugfs_add_files, 1478 .debugfs_init = wl18xx_debugfs_add_files,
1479 .scan_start = wl18xx_scan_start,
1480 .scan_stop = wl18xx_scan_stop,
1481 .sched_scan_start = wl18xx_sched_scan_start,
1482 .sched_scan_stop = wl18xx_scan_sched_scan_stop,
1323 .handle_static_data = wl18xx_handle_static_data, 1483 .handle_static_data = wl18xx_handle_static_data,
1324 .get_spare_blocks = wl18xx_get_spare_blocks, 1484 .get_spare_blocks = wl18xx_get_spare_blocks,
1325 .set_key = wl18xx_set_key, 1485 .set_key = wl18xx_set_key,
1486 .channel_switch = wl18xx_cmd_channel_switch,
1326 .pre_pkt_send = wl18xx_pre_pkt_send, 1487 .pre_pkt_send = wl18xx_pre_pkt_send,
1488 .sta_rc_update = wl18xx_sta_rc_update,
1489 .set_peer_cap = wl18xx_set_peer_cap,
1490 .lnk_high_prio = wl18xx_lnk_high_prio,
1491 .lnk_low_prio = wl18xx_lnk_low_prio,
1327}; 1492};
1328 1493
1329/* HT cap appropriate for wide channels in 2Ghz */ 1494/* HT cap appropriate for wide channels in 2Ghz */
1330static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = { 1495static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
1331 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | 1496 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1332 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40, 1497 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40 |
1498 IEEE80211_HT_CAP_GRN_FLD,
1333 .ht_supported = true, 1499 .ht_supported = true,
1334 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1500 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1335 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1501 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1343,7 +1509,8 @@ static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
1343/* HT cap appropriate for wide channels in 5Ghz */ 1509/* HT cap appropriate for wide channels in 5Ghz */
1344static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = { 1510static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
1345 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | 1511 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1346 IEEE80211_HT_CAP_SUP_WIDTH_20_40, 1512 IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1513 IEEE80211_HT_CAP_GRN_FLD,
1347 .ht_supported = true, 1514 .ht_supported = true,
1348 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1515 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1349 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1516 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1356,7 +1523,8 @@ static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
1356 1523
1357/* HT cap appropriate for SISO 20 */ 1524/* HT cap appropriate for SISO 20 */
1358static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = { 1525static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
1359 .cap = IEEE80211_HT_CAP_SGI_20, 1526 .cap = IEEE80211_HT_CAP_SGI_20 |
1527 IEEE80211_HT_CAP_GRN_FLD,
1360 .ht_supported = true, 1528 .ht_supported = true,
1361 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1529 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1362 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1530 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1369,7 +1537,8 @@ static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
1369 1537
1370/* HT cap appropriate for MIMO rates in 20mhz channel */ 1538/* HT cap appropriate for MIMO rates in 20mhz channel */
1371static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = { 1539static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
1372 .cap = IEEE80211_HT_CAP_SGI_20, 1540 .cap = IEEE80211_HT_CAP_SGI_20 |
1541 IEEE80211_HT_CAP_GRN_FLD,
1373 .ht_supported = true, 1542 .ht_supported = true,
1374 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1543 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1375 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1544 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1387,7 +1556,8 @@ static int wl18xx_setup(struct wl1271 *wl)
1387 1556
1388 wl->rtable = wl18xx_rtable; 1557 wl->rtable = wl18xx_rtable;
1389 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS; 1558 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
1390 wl->num_rx_desc = WL18XX_NUM_TX_DESCRIPTORS; 1559 wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
1560 wl->num_channels = 2;
1391 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES; 1561 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
1392 wl->band_rate_to_idx = wl18xx_band_rate_to_idx; 1562 wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
1393 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; 1563 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
@@ -1506,7 +1676,8 @@ static int wl18xx_probe(struct platform_device *pdev)
1506 int ret; 1676 int ret;
1507 1677
1508 hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv), 1678 hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv),
1509 WL18XX_AGGR_BUFFER_SIZE); 1679 WL18XX_AGGR_BUFFER_SIZE,
1680 sizeof(struct wl18xx_event_mailbox));
1510 if (IS_ERR(hw)) { 1681 if (IS_ERR(hw)) {
1511 wl1271_error("can't allocate hw"); 1682 wl1271_error("can't allocate hw");
1512 ret = PTR_ERR(hw); 1683 ret = PTR_ERR(hw);